Matlab Help Index Technical Documentation Index

m2html

NAME ^

M2HTML - Documentation System for Matlab M-files in HTML

SYNOPSIS ^

function m2html(varargin)

DESCRIPTION ^

M2HTML - Documentation System for Matlab M-files in HTML
  M2HTML by itself generates an HTML documentation of Matlab M-files in the
  current directory. HTML files are also written in the current directory.
  M2HTML('PropertyName1',PropertyValue1,'PropertyName2',PropertyValue2,...)
  sets multiple option values. The list of option names and default values is:
    o verbose - Verbose mode [ {on} | off ]
    o mFiles - Cell array of strings or character array containing the
       list of M-files and/or directories of M-files for which an HTML
       documentation will be built [ '.' ]
    o htmlDir - Top level directory for generated HTML files [ '.' ]
    o recursive - Process subdirectories [ on | {off} ]
    o matlabSource - Include Matlab source code in the HTML documentation
                               [ {on} | off ]
    o syntaxHighlighting - Syntax Highlighting [ {on} | off ]
    o useHorizontalTabs - Replace '\t' in source code by n white space
        characters [ 0 ... {4} ... n ]
    o globalHypertextLinks -  [ on | {off} ]
    o toDo - Create a TODO file in each directory summarizing all the
        '% TODO %' lines found in code [ on | {off}]
    o indexFile - Basename of the HTML index file [ 'index' ]
    o fileExtension - Extension of generated HTML files [ '.html' ]
    o template - HTML template name to use [ 'blue' ]

  See also TEMPLATE.

CROSS-REFERENCE INFORMATION ^

This function calls:

This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function m2html(varargin)
0002 %M2HTML - Documentation System for Matlab M-files in HTML
0003 %  M2HTML by itself generates an HTML documentation of Matlab M-files in the
0004 %  current directory. HTML files are also written in the current directory.
0005 %  M2HTML('PropertyName1',PropertyValue1,'PropertyName2',PropertyValue2,...)
0006 %  sets multiple option values. The list of option names and default values is:
0007 %    o verbose - Verbose mode [ {on} | off ]
0008 %    o mFiles - Cell array of strings or character array containing the
0009 %       list of M-files and/or directories of M-files for which an HTML
0010 %       documentation will be built [ '.' ]
0011 %    o htmlDir - Top level directory for generated HTML files [ '.' ]
0012 %    o recursive - Process subdirectories [ on | {off} ]
0013 %    o matlabSource - Include Matlab source code in the HTML documentation
0014 %                               [ {on} | off ]
0015 %    o syntaxHighlighting - Syntax Highlighting [ {on} | off ]
0016 %    o useHorizontalTabs - Replace '\t' in source code by n white space
0017 %        characters [ 0 ... {4} ... n ]
0018 %    o globalHypertextLinks -  [ on | {off} ]
0019 %    o toDo - Create a TODO file in each directory summarizing all the
0020 %        '% TODO %' lines found in code [ on | {off}]
0021 %    o indexFile - Basename of the HTML index file [ 'index' ]
0022 %    o fileExtension - Extension of generated HTML files [ '.html' ]
0023 %    o template - HTML template name to use [ 'blue' ]
0024 %
0025 %  See also TEMPLATE.
0026 
0027 %  Copyright (C) 2003 Guillaume Flandin <Guillaume.Flandin@sophia.inria.fr>
0028 %  INRIA Sophia Antipolis / CEA-SHFJ
0029 %  $Revision: 1.0 $Date: 2003/29/04 17:33:43 $
0030 
0031 %  This program is free software; you can redistribute it and/or
0032 %  modify it under the terms of the GNU General Public License
0033 %  as published by the Free Software Foundation; either version 2
0034 %  of the License, or any later version.
0035 %
0036 %  This program is distributed in the hope that it will be useful,
0037 %  but WITHOUT ANY WARRANTY; without even the implied warranty of
0038 %  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0039 %  GNU General Public License for more details.
0040 %
0041 %  You should have received a copy of the GNU General Public License
0042 %  along with this program; if not, write to the Free Software
0043 %  Foundation Inc, 59 Temple Pl. - Suite 330, Boston, MA 02111-1307, USA.
0044 
0045 %  Suggestions for improvement and fixes are always welcome, although no
0046 %  guarantee is made whether and when they will be implemented.
0047 %  Send requests to Guillaume.Flandin@sophia.inria.fr
0048 
0049 %  For tips on how to write Matlab code, see:
0050 %     * MATLAB Programming Style Guidelines, by R. Johnson:
0051 %       <http://www.datatool.com/prod02.htm>
0052 %     * For tips on creating help for your m-files 'type help.m'.
0053 %     * Matlab documentation on M-file Programming:
0054 %       <http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/ch10_pr9.shtml>
0055 
0056 %  This function uses the Template class so that you can fully customize
0057 %  the output. You can modify .tpl files in templates/blue/ or create new
0058 %  templates in a new directory.
0059 %  See the template class documentation for more details.
0060 
0061 %  Other Matlab to HTML converters available on the web:
0062 %  1/ mat2html.pl, J.C. Kantor, in Perl, 1995:
0063 %     <http://fresh.t-systems-sfr.com/unix/src/www/mat2html>
0064 %  2/ htmltools, B. Alsberg, in Matlab, 1997:
0065 %     <http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=175>
0066 %  3/ mtree2html2001, H. Pohlheim, in Perl, 1996, 2001:
0067 %     <http://www.pohlheim.com/perl_main.html#matlabdocu>
0068 %  4/ MatlabToHTML, T. Kristjansson, binary, 2001:
0069 %     <http://www.psi.utoronto.ca/~trausti/MatlabToHTML/MatlabToHTML.html>
0070 %  5/ mdoc, Peter Brinkmann, Matlab, 2003:
0071 %     <http://www.math.uiuc.edu/~brinkman/software/mdoc/>
0072 %  6/ Ocamaweb, Miriad Technologies, Ocaml, 2002:
0073 %     <http://ocamaweb.sourceforge.net/>
0074 %  7/ Matdoc, Moshe Kaminsky, Matlab, 2003:
0075 %     <http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=3498>
0076 %  8/ Matlab itself, The Mathworks Inc, with HELPWIN and DOC
0077 
0078 %-------------------------------------------------------------------------------
0079 %- Set up options
0080 %-------------------------------------------------------------------------------
0081 msgInvalidPair = 'Invalid parameter/value pair arguments.';
0082 if mod(nargin,2)
0083     error(msgInvalidPair);
0084 end
0085 
0086 options = struct('verbose', 1,...
0087                  'mFiles', {{'.'}},...
0088                  'htmlDir', '.',...
0089                  'recursive', 0,...
0090                  'matlabSource', 1,...
0091                  'syntaxHighlighting', 1,...
0092                  'useHorizontalTabs',4,...
0093                  'globalHypertextLinks', 0,...
0094                  'toDo', 0,...
0095                  'indexFile','index',...
0096                  'fileExtension', '.html',...
0097                  'template','blue');
0098 for i=1:2:nargin
0099     switch(lower(varargin{i}))
0100         case {'verbose', 'v'}
0101             if strcmpi(varargin{i+1},'on')
0102                 options.verbose = 1;
0103             elseif strcmpi(varargin{i+1},'off')
0104                 options.verbose = 0;
0105             else
0106                 error(msgInvalidPair);
0107             end
0108         case {'mfiles', 'm'}
0109             if iscellstr(varargin{i+1})
0110                 options.mFiles = varargin{i+1};
0111             elseif ischar(varargin{i+1})
0112                 options.mFiles = cellstr(varargin{i+1});
0113             else
0114                 error(msgInvalidPair);
0115             end
0116         case {'htmldir', 'html'}
0117             if ischar(varargin{i+1})
0118                 if isempty(varargin{i+1}),
0119                     options.htmlDir = '.';
0120                 else
0121                     options.htmlDir = varargin{i+1};
0122                 end
0123                 if isempty(dir(options.htmlDir))
0124                     %- Create the top level HTML directory
0125                     if options.verbose
0126                         fprintf('Creating directory %s...\n',options.htmlDir);
0127                     end
0128                     if options.htmlDir(end) == filesep,
0129                         options.htmlDir(end) = [];
0130                     end
0131                     [pathdir, namedir] = fileparts(options.htmlDir);
0132                     if isempty(pathdir)
0133                         [status, msg] = mkdir(namedir);
0134                     else
0135                         [status, msg] = mkdir(pathdir, namedir);
0136                     end
0137                     error(msg);
0138                 end
0139             else
0140                 error(msgInvalidPair);
0141             end
0142         case {'recursive', 'r'}
0143             if strcmpi(varargin{i+1},'on')
0144                 options.recursive = 1;
0145             elseif strcmpi(varargin{i+1},'off')
0146                 options.recursive = 0;
0147             else
0148                 error(msgInvalidPair);
0149             end
0150         case {'matlabsource', 'source'}
0151             if strcmpi(varargin{i+1},'on')
0152                 options.matlabSource = 1;
0153             elseif strcmpi(varargin{i+1},'off')
0154                 options.matlabSource = 0;
0155             else
0156                 error(msgInvalidPair);
0157             end
0158         case {'syntaxhighlighting', 'highlight'}
0159             if strcmpi(varargin{i+1},'on')
0160                 options.syntaxHighlighting = 1;
0161             elseif strcmpi(varargin{i+1},'off')
0162                 options.syntaxHighlighting = 0;
0163             else
0164                 error(msgInvalidPair);
0165             end
0166         case {'usehorizontaltabs', 'tab', 'tabs'}
0167             if varargin{i+1} >= 0
0168                 options.useHorizontalTabs = varargin{i+1};
0169             else
0170                 error(msgInvalidPair);
0171             end
0172         case {'globalhypertextlinks', 'glinks', 'global'}
0173             if strcmpi(varargin{i+1},'on')
0174                 options.globalHypertextLinks = 1;
0175             elseif strcmpi(varargin{i+1},'off')
0176                 options.globalHypertextLinks = 0;
0177             else
0178                 error(msgInvalidPair);
0179             end
0180         case {'todo'}
0181             if strcmpi(varargin{i+1},'on')
0182                 options.toDo = 1;
0183             elseif strcmpi(varargin{i+1},'off')
0184                 options.toDO = 0;
0185             else
0186                 error(msgInvalidPair);
0187             end
0188         case {'indexfile', 'index'}
0189             if ischar(varargin{i+1})
0190                 options.indexFile = varargin{i+1};
0191             else
0192                 error(msgInvalidPair);
0193             end
0194         case {'fileextension', 'ext'}
0195             if ischar(varargin{i+1}) & varargin{i+1}(1) == '.'
0196                 options.fileExtension = varargin{i+1};
0197             else
0198                 error(msgInvalidPair);
0199             end
0200         case {'template', 'tpl'}
0201             if ischar(varargin{i+1})
0202                 options.template = varargin{i+1};
0203             else
0204                 error(msgInvalidPair);
0205             end
0206         otherwise
0207             error(msgInvalidPair);
0208     end
0209 end
0210 
0211 %-------------------------------------------------------------------------------
0212 %- Define a few variables
0213 %-------------------------------------------------------------------------------
0214 %- Delimiters used in strtok: some of them may be useless (% " .), removed '.'
0215 strtok_delim = sprintf(' \t\n\r(){}[]<>+-*~!|\\@&/,:;="''%%');
0216 
0217 %-------------------------------------------------------------------------------
0218 %- Get template files location
0219 %-------------------------------------------------------------------------------
0220 s = fileparts(which(mfilename));
0221 options.template = fullfile(s,'templates',options.template);
0222 
0223 %-------------------------------------------------------------------------------
0224 %- Get list of M-files
0225 %-------------------------------------------------------------------------------
0226 mfiles = getmfiles(options.mFiles,{},options.recursive);
0227 if ~length(mfiles), fprintf('Nothing to be done.\n'); return; end
0228 if options.verbose,
0229     fprintf('Found %d M-files.\n',length(mfiles));
0230 end
0231 mfiles = sort(mfiles); % sort list of M-files in dictionary order
0232 
0233 %-------------------------------------------------------------------------------
0234 %- Get list of (unique) directories and (unique) names
0235 %-------------------------------------------------------------------------------
0236 mdirs = {};
0237 names = {};
0238 for i=1:length(mfiles)
0239     [mdirs{i}, names{i}] = fileparts(mfiles{i});
0240     if isempty(mdirs{i}), mdirs{i} = '.'; end
0241 end
0242 
0243 mdir = unique(mdirs);
0244 if options.verbose,
0245     fprintf('Found %d unique Matlab directories.\n',length(mdir));
0246 end
0247 name = names;
0248 %name = unique(names); % output is sorted
0249 if options.verbose,
0250     fprintf('Found %d unique Matlab identifiers.\n',length(name));
0251 end
0252 
0253 %-------------------------------------------------------------------------------
0254 %- Get synopsis, H1 line, script/function, subroutines, cross-references
0255 %-------------------------------------------------------------------------------
0256 synopsis = cell(size(mfiles));
0257 h1line = cell(size(mfiles));
0258 subroutine = cell(size(mfiles));
0259 hrefs  = sparse(length(mfiles),length(mfiles));
0260 todo = struct('mfile',[],'line',[],'comment',{{}});
0261 for i=1:length(mfiles)
0262     %- Open for reading the M-file
0263     if options.verbose
0264         fprintf('Processing file %s...\n',mfiles{i});
0265     end
0266     fid = openfile(mfiles{i},'r');
0267     it = 0; % line number
0268     %- Initialize Synopsis and H1 Line
0269     synopsis{i} = '';
0270     h1line{i} = '';
0271     %- Initialize flag for synopsis cont ('...')
0272     flagsynopcont = 0;
0273     %- Look for synopsis and H1 line
0274     %  Help is the first set of contiguous comment lines in an m-file
0275     %  The H1 line is a short one-line description into the first help line
0276     while 1
0277         tline = fgetl(fid);
0278         if ~ischar(tline), break, end
0279         it = it + 1;
0280         tline = deblank(fliplr(deblank(fliplr(tline))));
0281         %- Synopsis line
0282         if ~isempty(strmatch('function',tline))
0283             synopsis{i} = tline;
0284             if ~isempty(strmatch('...',fliplr(tline)))
0285                 flagsynopcont = 1;
0286                 synopsis{i} = deblank(synopsis{i}(1:end-3));
0287             end
0288         %- H1 Line
0289         elseif ~isempty(strmatch('%',tline))
0290             % allow for the help lines to be before the synopsis
0291             if isempty(h1line{i})
0292                 h1line{i} = fliplr(deblank(tline(end:-1:2)));
0293             end
0294             if ~isempty(synopsis{i}), break, end
0295         %- Go through empty lines
0296         elseif isempty(tline)
0297             
0298         %- Code found. Stop.
0299         else
0300             if flagsynopcont
0301                 if isempty(strmatch('...',fliplr(tline)))
0302                     synopsis{i} = [synopsis{i} tline];
0303                     flagsynopcont = 0;
0304                 else
0305                     synopsis{i} = [synopsis{i} deblank(tline(1:end-3))];
0306                 end
0307             else
0308                 break;
0309             end
0310         end
0311     end
0312     %- Global Hypertext Links option
0313     %  If false, hypertext links are done only among functions in the same
0314     %  directory.
0315     if options.globalHypertextLinks
0316         hrefnames = names;
0317     else
0318         indhref = find(strcmp(mdirs{i},mdirs));
0319         hrefnames = {names{indhref}};
0320     end
0321     %- Compute cross-references and extract subroutines
0322     %  hrefs(i,j) is 1 if mfiles{i} calls mfiles{j} and 0 otherwise
0323     while ischar(tline)
0324         % Remove blanks at both ends
0325         tline = deblank(fliplr(deblank(fliplr(tline))));
0326         
0327         % Split code into meaningful chunks
0328         splitc = splitcode(tline);
0329         for j=1:length(splitc)
0330             if isempty(splitc{j}) | ...
0331                 splitc{j}(1) == '''' | ...
0332                 ~isempty(strmatch('...',splitc{j}))
0333                 % Forget about empty lines, char strings or conts
0334             elseif splitc{j}(1) == '%'
0335                 % Cross-references are not taken into account in comments
0336                 % Just look for potential TODO line
0337                 if options.toDo
0338                     if ~isempty(strmatch('% TODO %',splitc{j}))
0339                         todo.mfile  = [todo.mfile i];
0340                         todo.line   = [todo.line it];
0341                         todo.comment{end+1} = splitc{j}(9:end);
0342                     end
0343                 end
0344             else
0345                 % detect if this line is a declaration of a subroutine
0346                 if ~isempty(strmatch('function',splitc{j}))
0347                     subroutine{i}{end+1} = splitc{j};
0348                 else
0349                     % get list of variables and functions
0350                     symbol = {};
0351                     while 1
0352                         [t,splitc{j}] = strtok(splitc{j},strtok_delim);
0353                         if isempty(t), break, end;
0354                         symbol{end+1} = t;
0355                     end
0356                     if options.globalHypertextLinks
0357                         hrefs(i,:) = hrefs(i,:) + ismember(hrefnames,symbol);
0358                     else
0359                         hrefs(i,indhref) = hrefs(i,indhref) + ...
0360                                            ismember(hrefnames,symbol);
0361                     end
0362                 end
0363             end
0364         end
0365         tline = fgetl(fid);
0366         it = it + 1;
0367     end    
0368     fclose(fid);
0369 end
0370 hrefs = hrefs > 0;
0371 
0372 %-------------------------------------------------------------------------------
0373 %- Setup the HTML directories
0374 %-------------------------------------------------------------------------------
0375 for i=1:length(mdir)
0376     if ~(exist(fullfile(options.htmlDir,mdir{i})) == 7)
0377         ldir = splitpath(mdir{i});
0378         for j=1:length(ldir)
0379             if ~(exist(fullfile(options.htmlDir,ldir{1:j})) == 7)
0380                 %- Create the HTML directory
0381                 if options.verbose
0382                     fprintf('Creating directory %s...\n',...
0383                             fullfile(options.htmlDir,ldir{1:j}));
0384                 end
0385                 if j == 1
0386                     [status, msg] = mkdir(options.htmlDir,ldir{1});
0387                 else
0388                     [status, msg] = mkdir(options.htmlDir,fullfile(ldir{1:j}));
0389                 end
0390                 error(msg);
0391             end
0392         end
0393     end
0394 end
0395 
0396 %-------------------------------------------------------------------------------
0397 %- Write the master index file
0398 %-------------------------------------------------------------------------------
0399 tpl_master = 'master.tpl';
0400 tpl_master_identifier_nbyline = 4;
0401 
0402 %- Create the HTML template
0403 tpl = template(options.template,'remove');
0404 tpl = set(tpl,'file','TPL_MASTER',tpl_master);
0405 tpl = set(tpl,'block','TPL_MASTER','rowdir','rowdirs');
0406 tpl = set(tpl,'block','TPL_MASTER','idrow','idrows');
0407 tpl = set(tpl,'block','idrow','idcolumn','idcolumns');
0408 
0409 %- Open for writing the HTML master index file
0410 curfile = fullfile(options.htmlDir,[options.indexFile options.fileExtension]);
0411 if options.verbose
0412     fprintf('Creating HTML file %s...\n',curfile);
0413 end
0414 fid = openfile(curfile,'w');
0415 
0416 %- Set some template variables
0417 tpl = set(tpl,'var','DATE',[datestr(now,13) ' ' datestr(now,1)]);
0418 tpl = set(tpl,'var','MASTERPATH',       './');
0419 tpl = set(tpl,'var','DIRS',    sprintf('%s ',mdir{:}));
0420 
0421 %- Print list of unique directories
0422 for i=1:length(mdir)
0423     tpl = set(tpl,'var','L_DIR',...
0424               fullurl(mdir{i},[options.indexFile options.fileExtension]));
0425     tpl = set(tpl,'var','DIR',mdir{i});
0426     tpl = parse(tpl,'rowdirs','rowdir',1);
0427 end
0428 
0429 %- Print full list of M-files
0430 for i=1:length(names)
0431     tpl = set(tpl,'var','L_IDNAME',...
0432               fullurl(mdirs{i},[names{i} options.fileExtension]));
0433     tpl = set(tpl,'var','IDNAME',names{i});
0434     tpl = parse(tpl,'idcolumns','idcolumn',1);
0435     if mod(i,tpl_master_identifier_nbyline) == 0
0436         tpl = parse(tpl,'idrows','idrow',1);
0437         tpl = set(tpl,'var','idcolumns','');
0438     elseif i == length(names)
0439         tpl = parse(tpl,'idrows','idrow',1);
0440     end
0441 end
0442 
0443 %- Print the template in the HTML file
0444 tpl = parse(tpl,'OUT','TPL_MASTER');
0445 fprintf(fid,'%s',get(tpl,'OUT'));
0446 fclose(fid);
0447 
0448 %-------------------------------------------------------------------------------
0449 %- Copy template files (CSS, images, ...)
0450 %-------------------------------------------------------------------------------
0451 % Get list of files
0452 d = dir(options.template);
0453 d = {d(~[d.isdir]).name};
0454 % Copy files
0455 for i=1:length(d)
0456     [p, n, ext] = fileparts(d{i});
0457     if ~strcmp(ext,'.tpl') % do not copy .tpl files
0458         if ~(exist(fullfile(options.htmlDir,d{i})))
0459             if options.verbose
0460                 fprintf('Copying template file %s...\n',d{i});
0461             end
0462             [status, errmsg] = copyfile(fullfile(options.template,d{i}),...
0463                                         options.htmlDir);
0464             error(errmsg);
0465         end
0466     end
0467 end
0468 
0469 %-------------------------------------------------------------------------------
0470 %- Write an index for each HTML directory
0471 %-------------------------------------------------------------------------------
0472 tpl_mdir = 'mdir.tpl';
0473 tpl_mdir_link = '<a href="%s">%s</a>';
0474 
0475 %- Create the HTML template
0476 tpl = template(options.template,'remove');
0477 tpl = set(tpl,'file','TPL_MDIR',tpl_mdir);
0478 tpl = set(tpl,'block','TPL_MDIR','row-m','rows-m');
0479 tpl = set(tpl,'block','TPL_MDIR','row-other','rows-other');
0480 tpl = set(tpl,'block','TPL_MDIR','subdir','subdirs');
0481 tpl = set(tpl,'block','TPL_MDIR','todolist','todolists');
0482 tpl = set(tpl,'var','DATE',[datestr(now,13) ' ' datestr(now,1)]);
0483 
0484 for i=1:length(mdir)
0485     %- Open for writing each HTML directory index file
0486     curfile = fullfile(options.htmlDir,mdir{i},...
0487                        [options.indexFile options.fileExtension]);
0488     if options.verbose
0489         fprintf('Creating HTML file %s...\n',curfile);
0490     end
0491     fid = openfile(curfile,'w');
0492 
0493     %- Set template fields
0494     tpl = set(tpl,'var','INDEX',     [options.indexFile options.fileExtension]);
0495     tpl = set(tpl,'var','MASTERPATH',backtomaster(mdir{i}));
0496     tpl = set(tpl,'var','MDIR',      mdir{i});
0497     
0498     %- Display Matlab m-files and their H1 line
0499     tpl = set(tpl,'var','rows-m','');
0500     for j=1:length(mdirs)
0501         if strcmp(mdirs{j},mdir{i})
0502             tpl = set(tpl,'var','L_NAME', [names{j} options.fileExtension]);
0503             tpl = set(tpl,'var','NAME',   names{j});
0504             tpl = set(tpl,'var','H1LINE', h1line{j});
0505             tpl = parse(tpl,'rows-m','row-m',1);
0506         end
0507     end
0508     
0509     %- Display other Matlab-specific files (.mat,.mdl,.p)
0510     tpl = set(tpl,'var','rows-other','');
0511     w = what(mdir{i});
0512     w = w(1);
0513     for j=1:length(w.mat)
0514         tpl = set(tpl,'var','OTHERFILE',w.mat{j});
0515         tpl = parse(tpl,'rows-other','row-other',1);
0516     end
0517     for j=1:length(w.mdl)
0518         tpl = set(tpl,'var','OTHERFILE',w.mdl{j});
0519         tpl = parse(tpl,'rows-other','row-other',1);
0520     end
0521     for j=1:length(w.p)
0522         tpl = set(tpl,'var','OTHERFILE',w.p{j});
0523         tpl = parse(tpl,'rows-other','row-other',1);
0524     end
0525     
0526     %- Display subsequent directories and classes
0527     tpl = set(tpl,'var','subdirs','');
0528     d = dir(mdir{i});
0529     d = {d([d.isdir]).name};
0530     d = {d{~ismember(d,{'.' '..'})}};
0531     for j=1:length(d)
0532         if ismember(fullfile(mdir{i},d{j}),mdir)
0533             tpl = set(tpl,'var','SUBDIRECTORY',...
0534                 sprintf(tpl_mdir_link,...
0535                 fullurl(d{j},[options.indexFile options.fileExtension]),d{j}));
0536         else
0537             tpl = set(tpl,'var','SUBDIRECTORY',d{j});
0538         end
0539         tpl = parse(tpl,'subdirs','subdir',1);
0540     end
0541     
0542     %- Link to the TODO list if necessary
0543     tpl = set(tpl,'var','todolists','');
0544     if options.toDo
0545         if ~isempty(intersect(find(strcmp(mdir{i},mdirs)),todo.mfile))
0546             tpl = set(tpl,'var','LTODOLIST',['todo' options.fileExtension]);
0547             tpl = parse(tpl,'todolists','todolist',1);
0548         end
0549     end
0550     
0551     %- Print the template in the HTML file
0552     tpl = parse(tpl,'OUT','TPL_MDIR');
0553     fprintf(fid,'%s',get(tpl,'OUT'));
0554     fclose(fid);
0555 end
0556 
0557 %-------------------------------------------------------------------------------
0558 %- Write a TODO list file for each HTML directory, if necessary
0559 %-------------------------------------------------------------------------------
0560 tpl_todo = 'todo.tpl';
0561 
0562 %- Create the HTML template
0563 tpl = template(options.template,'remove');
0564 tpl = set(tpl,'file','TPL_TODO',tpl_todo);
0565 tpl = set(tpl,'block','TPL_TODO','filelist','filelists');
0566 tpl = set(tpl,'block','filelist','row','rows');
0567 tpl = set(tpl,'var','DATE',[datestr(now,13) ' ' datestr(now,1)]);
0568 
0569 if options.toDo
0570     for i=1:length(mdir)
0571         mfilestodo = intersect(find(strcmp(mdir{i},mdirs)),todo.mfile);
0572         if ~isempty(mfilestodo)
0573             %- Open for writing each TODO list file
0574             curfile = fullfile(options.htmlDir,mdir{i},...
0575                                ['todo' options.fileExtension]);
0576             if options.verbose
0577                 fprintf('Creating HTML file %s...\n',curfile);
0578             end
0579             fid = openfile(curfile,'w');
0580             
0581             %- Set template fields
0582             tpl = set(tpl,'var','INDEX',[options.indexFile options.fileExtension]);
0583             tpl = set(tpl,'var','MASTERPATH', backtomaster(mdir{i}));
0584             tpl = set(tpl,'var','MDIR',       mdir{i});
0585     
0586             for k=1:length(mfilestodo)
0587                 tpl = set(tpl,'var','MFILE',names{mfilestodo(k)});
0588                 tpl = set(tpl,'var','rows','');
0589                 nbtodo = find(todo.mfile == mfilestodo(k));
0590                 for l=1:length(nbtodo)
0591                     tpl = set(tpl,'var','L_NBLINE',...
0592                         [names{mfilestodo(k)} ...
0593                             options.fileExtension ...
0594                             '#l' num2str(todo.line(nbtodo(l)))]);
0595                     tpl = set(tpl,'var','NBLINE',num2str(todo.line(nbtodo(l))));
0596                     tpl = set(tpl,'var','COMMENT',todo.comment{nbtodo(l)});
0597                     tpl = parse(tpl,'rows','row',1);
0598                 end
0599                 tpl = parse(tpl,'filelists','filelist',1);
0600             end
0601     
0602             %- Print the template in the HTML file
0603             tpl = parse(tpl,'OUT','TPL_TODO');
0604             fprintf(fid,'%s',get(tpl,'OUT'));
0605             fclose(fid);
0606         end
0607     end
0608 end
0609 
0610 %-------------------------------------------------------------------------------
0611 %- Write an HTML file for each M-file
0612 %-------------------------------------------------------------------------------
0613 %- List of Matlab keywords (output from iskeyword)
0614 matlabKeywords = {'break', 'case', 'catch', 'continue', 'elseif', 'else', ...
0615                   'end', 'for', 'function', 'global', 'if', 'otherwise', ...
0616                   'persistent', 'return', 'switch', 'try', 'while'};
0617                   %'keyboard', 'pause', 'eps', 'NaN', 'Inf'
0618 
0619 tpl_mfile = 'mfile.tpl';
0620 
0621 tpl_mfile_code     = '<a href="%s" class="code" title="%s">%s</a>';
0622 tpl_mfile_keyword  = '<span class="keyword">%s</span>';
0623 tpl_mfile_comment  = '<span class="comment">%s</span>';
0624 tpl_mfile_string   = '<span class="string">%s</span>';
0625 tpl_mfile_aname    = '<a name="%s" href="#_subfunctions" class="code">%s</a>';
0626 tpl_mfile_line     = '%04d %s\n';
0627 
0628 %- Create the HTML template
0629 tpl = template(options.template,'remove');
0630 tpl = set(tpl,'file','TPL_MFILE',tpl_mfile);
0631 tpl = set(tpl,'block','TPL_MFILE','script','scriptfile');
0632 tpl = set(tpl,'block','TPL_MFILE','crossrefcall','crossrefcalls');
0633 tpl = set(tpl,'block','TPL_MFILE','crossrefcalled','crossrefcalleds');
0634 tpl = set(tpl,'block','TPL_MFILE','subfunction','subfunctions');
0635 tpl = set(tpl,'block','TPL_MFILE','nosubfunction','nosubf');
0636 tpl = set(tpl,'block','TPL_MFILE','source','thesource');
0637 tpl = set(tpl,'var','DATE',[datestr(now,13) ' ' datestr(now,1)]);
0638 
0639 for i=1:length(mdir)
0640     for j=1:length(mdirs)
0641         if strcmp(mdirs{j},mdir{i})
0642         
0643             curfile = fullfile(options.htmlDir,mdir{i},...
0644                                [names{j} options.fileExtension]);
0645 
0646             %- Open for writing the HTML file
0647             if options.verbose
0648                 fprintf('Creating HTML file %s...\n',curfile);
0649             end
0650             fid = openfile(curfile,'w');
0651             
0652             %- Open for reading the M-file
0653             fid2 = openfile(mfiles{j},'r');
0654             
0655             %- Set some template fields
0656             tpl = set(tpl,'var','INDEX', [options.indexFile options.fileExtension]);
0657             tpl = set(tpl,'var','MASTERPATH',       backtomaster(mdir{i}));
0658             tpl = set(tpl,'var','MDIR',             mdirs{j});
0659             tpl = set(tpl,'var','NAME',             names{j});
0660             tpl = set(tpl,'var','H1LINE',           h1line{j});
0661             tpl = set(tpl,'var','scriptfile',       '');
0662             if isempty(synopsis{j})
0663                 tpl = set(tpl,'var','SYNOPSIS',get(tpl,'var','script'));
0664             else
0665                 tpl = set(tpl,'var','SYNOPSIS', synopsis{j});
0666             end
0667             
0668             %- Set description template field
0669             descr = '';
0670             flagsynopcont = 0;
0671             flag_seealso  = 0;
0672             while 1
0673                 tline = fgets(fid2);
0674                 if ~ischar(tline), break, end
0675                 tline = entity(fliplr(deblank(fliplr(tline))));
0676                 %- Synopsis line
0677                 if ~isempty(strmatch('function',tline))
0678                     if ~isempty(strmatch('...',fliplr(deblank(tline))))
0679                         flagsynopcont = 1;
0680                     end
0681                 %- H1 line and description
0682                 elseif ~isempty(strmatch('%',tline))
0683                     %- Hypertext links on the "See also" line
0684                     ind = findstr(lower(tline),'see also');
0685                     if ~isempty(ind) | flag_seealso
0686                         %- "See also" only in files in the same directory
0687                         indsamedir = find(strcmp(mdirs{j},mdirs));
0688                         hrefnames = {names{indsamedir}};
0689                         r = deblank(tline);
0690                         flag_seealso = 1; %(r(end) == ',');
0691                         tline = '';
0692                         while 1
0693                             [t,r,q] = strtok(r,sprintf(' \t\n\r.,;%%'));
0694                             tline = [tline q];
0695                             if isempty(t), break, end;
0696                             ii = strcmpi(hrefnames,t);
0697                             if any(ii)
0698                                 jj = find(ii);
0699                                 tline = [tline sprintf(tpl_mfile_code,...
0700                                     [hrefnames{jj(1)} options.fileExtension],...
0701                                     synopsis{indsamedir(jj(1))},t)];
0702                             else
0703                                 tline = [tline t];
0704                             end
0705                         end
0706                         tline = sprintf('%s\n',tline);
0707                     end
0708                     descr = [descr tline(2:end)];
0709                 elseif isempty(tline)
0710                     if ~isempty(descr), break, end;
0711                 else
0712                     if flagsynopcont
0713                         if isempty(strmatch('...',fliplr(deblank(tline))))
0714                             flagsynopcont = 0;
0715                         end
0716                     else
0717                         break;
0718                     end
0719                 end
0720             end
0721             tpl = set(tpl,'var','DESCRIPTION',...
0722                 horztab(descr,options.useHorizontalTabs));
0723             
0724             %- Set cross-references template fields:
0725             ind = find(hrefs(j,:) == 1);
0726             tpl = set(tpl,'var','crossrefcalls','');
0727             for k=1:length(ind)
0728                 if strcmp(mdirs{j},mdirs{ind(k)})
0729                     tpl = set(tpl,'var','L_NAME_CALL', ...
0730                         [names{ind(k)} options.fileExtension]);
0731                 else
0732                     tpl = set(tpl,'var','L_NAME_CALL', ...
0733                               fullurl(backtomaster(mdirs{j}), ...
0734                                          mdirs{ind(k)}, ...
0735                                        [names{ind(k)} options.fileExtension]));
0736                 end
0737                 tpl = set(tpl,'var','NAME_CALL',   names{ind(k)});
0738                 tpl = set(tpl,'var','H1LINE_CALL', h1line{ind(k)});
0739                 tpl = parse(tpl,'crossrefcalls','crossrefcall',1);
0740             end
0741             if isempty(ind), tpl = set(tpl,'var','crossrefcalls',''); end
0742             ind = find(hrefs(:,j) == 1);
0743             tpl = set(tpl,'var','crossrefcalleds','');
0744             for k=1:length(ind)
0745                 if strcmp(mdirs{j},mdirs{ind(k)})
0746                     tpl = set(tpl,'var','L_NAME_CALLED', ...
0747                         [names{ind(k)} options.fileExtension]);
0748                 else
0749                     tpl = set(tpl,'var','L_NAME_CALLED', ...
0750                         fullurl(backtomaster(mdirs{j}),...
0751                             mdirs{ind(k)}, ...
0752                             [names{ind(k)} options.fileExtension]));
0753                 end
0754                 tpl = set(tpl,'var','NAME_CALLED',   names{ind(k)});
0755                 tpl = set(tpl,'var','H1LINE_CALLED', h1line{ind(k)});
0756                 tpl = parse(tpl,'crossrefcalleds','crossrefcalled',1);
0757             end
0758             if isempty(ind), tpl = set(tpl,'var','crossrefcalleds',''); end
0759             
0760             %- Set subfunction template field
0761             tpl = set(tpl,'var','subfunctions','');
0762             if isempty(subroutine{j})
0763                 tpl = set(tpl,'var','nosubf',get(tpl,'var','nosubfunction'));
0764             else
0765                 tpl = set(tpl,'var','nosubf','');
0766                 for k=1:length(subroutine{j})
0767                     tpl = set(tpl,'var','L_SUB', ['#_sub' num2str(k)]);
0768                     tpl = set(tpl,'var','SUB',   subroutine{j}{k});
0769                     tpl = parse(tpl,'subfunctions','subfunction',1);
0770                 end
0771             end
0772             
0773             %- Display source code with cross-references
0774             if options.matlabSource
0775                 fseek(fid2,0,-1);
0776                 it = 1;
0777                 matlabsource = '';
0778                 nbsubroutine = 1;
0779                 %- Get href function names of this file
0780                 indhrefnames = find(hrefs(j,:) == 1);
0781                 hrefnames = {names{indhrefnames}};
0782                 %- Loop over lines
0783                 while 1
0784                     tline = fgetl(fid2);
0785                     if ~ischar(tline), break, end
0786                     myline = '';
0787                     splitc = splitcode(entity(tline));
0788                     for k=1:length(splitc)
0789                         if isempty(splitc{k})
0790                         elseif ~isempty(strmatch('function',splitc{k}))
0791                             %- Subfunctions definition
0792                             myline = [myline ...
0793                                 sprintf(tpl_mfile_aname,...
0794                                     ['_sub' num2str(nbsubroutine-1)],splitc{k})];
0795                             nbsubroutine = nbsubroutine + 1;
0796                         elseif splitc{k}(1) == ''''
0797                             myline = [myline ...
0798                                 sprintf(tpl_mfile_string,splitc{k})];
0799                         elseif splitc{k}(1) == '%'
0800                             myline = [myline ...
0801                                 sprintf(tpl_mfile_comment,deblank(splitc{k}))];
0802                         elseif ~isempty(strmatch('...',splitc{k}))
0803                             myline = [myline sprintf(tpl_mfile_keyword,'...')];
0804                             if ~isempty(splitc{k}(4:end))
0805                                 myline = [myline ...
0806                                     sprintf(tpl_mfile_comment,splitc{k}(4:end))];
0807                             end
0808                         else
0809                             %- Look for keywords
0810                             r = splitc{k};
0811                             while 1
0812                                 [t,r,q] = strtok(r,strtok_delim);
0813                                 myline = [myline q];
0814                                 if isempty(t), break, end;
0815                                 %- Highlight Matlab keywords &
0816                                 %  cross-references on known functions
0817                                 if options.syntaxHighlighting & ...
0818                                         any(strcmp(matlabKeywords,t))
0819                                     if strcmp('end',t)
0820                                         rr = fliplr(deblank(fliplr(r)));
0821                                         icomma = strmatch(',',rr);
0822                                         isemicolon = strmatch(';',rr);
0823                                         if ~(isempty(rr) | ~isempty([icomma isemicolon]))
0824                                             myline = [myline t];
0825                                         else
0826                                             myline = [myline sprintf(tpl_mfile_keyword,t)];
0827                                         end
0828                                     else
0829                                         myline = [myline sprintf(tpl_mfile_keyword,t)];
0830                                     end
0831                                 elseif any(strcmp(hrefnames,t))
0832                                     indt = indhrefnames(logical(strcmp(hrefnames,t)));
0833                                     flink = [t options.fileExtension];
0834                                     ii = ismember({mdirs{indt}},mdirs{j});
0835                                     if ~any(ii)
0836                                         % take the first one...
0837                                         flink = fullurl(backtomaster(mdirs{j}),...
0838                                                           mdirs{indt(1)}, flink);
0839                                     else
0840                                         indt = indt(logical(ii));
0841                                     end
0842                                     myline = [myline sprintf(tpl_mfile_code,...
0843                                               flink, synopsis{indt(1)}, t)];
0844                                 else
0845                                     myline = [myline t];
0846                                 end
0847                             end
0848                         end
0849                     end
0850                     matlabsource = [matlabsource sprintf(tpl_mfile_line,it,myline)];
0851                     it = it + 1;
0852                 end
0853                 tpl = set(tpl,'var','SOURCECODE',...
0854                           horztab(matlabsource,options.useHorizontalTabs));
0855                 tpl = parse(tpl,'thesource','source');
0856             else
0857                 tpl = set(tpl,'var','thesource','');
0858             end
0859             tpl = parse(tpl,'OUT','TPL_MFILE');
0860             fprintf(fid,'%s',get(tpl,'OUT'));
0861             fclose(fid2);
0862             fclose(fid);
0863         end
0864     end
0865 end
0866 
0867 %===============================================================================
0868 function mfiles = getmfiles(mdirs,mfiles,recursive)
0869     for i=1:length(mdirs)
0870         if exist(mdirs{i}) == 2 % M-file
0871             mfiles{end+1} = mdirs{i};
0872         elseif exist(mdirs{i}) == 7 % Directory
0873             w = what(mdirs{i});
0874             w = w(1); %- Sometimes an array is returned...
0875             for j=1:length(w.m)
0876                 mfiles{end+1} = fullfile(mdirs{i},w.m{j});
0877             end
0878             if recursive
0879                 d = dir(mdirs{i});
0880                 d = {d([d.isdir]).name};
0881                 d = {d{~ismember(d,{'.' '..'})}};
0882                 for j=1:length(d)
0883                     mfiles = getmfiles(cellstr(fullfile(mdirs{i},d{j})),...
0884                                        mfiles,recursive);
0885                 end
0886             end
0887         else
0888             fprintf('Warning: Unprocessed file %s.\n',mdirs{i});
0889         end
0890     end
0891 
0892 %===============================================================================
0893 function fid = openfile(filename,permission)
0894     [fid, errmsg] = fopen(filename,permission);
0895     if ~isempty(errmsg)
0896         switch permission
0897             case 'r'
0898                 error(sprintf('Cannot open %s in read mode.',filename));
0899             case 'w'
0900                 error(sprintf('Cannot open %s in write mode.',filename));
0901             otherwise
0902                 error(errmsg);
0903         end
0904     end
0905 
0906 %===============================================================================
0907 function s = backtomaster(mdir)
0908     ldir = splitpath(mdir);
0909     s = repmat('../',1,length(ldir));
0910     
0911 %===============================================================================
0912 function ldir = splitpath(p)
0913     ldir = {};
0914     p = deblank(p);
0915     while 1
0916         [t,p] = strtok(p,filesep);
0917         if isempty(t), break; end
0918         if ~strcmp(t,'.')
0919             ldir{end+1} = t;
0920         end
0921     end
0922     if isempty(ldir)
0923         ldir{1} = '.'; % should be removed
0924     end
0925 
0926 %===============================================================================
0927 function f = fullurl(varargin)
0928 %FULLURL Build full url from parts (using '/' and not filesep)
0929 
0930     f = strrep(fullfile(varargin{:}),'\','/');
0931 
0932 %===============================================================================
0933 function str = entity(str)
0934     %- See http://www.w3.org/TR/html4/charset.html#h-5.3.2
0935     str = strrep(str,'&','&amp;');
0936     str = strrep(str,'<','&lt;');
0937     str = strrep(str,'>','&gt;');
0938     str = strrep(str,'"','&quot;');
0939     
0940 %===============================================================================
0941 function str = horztab(str,n)
0942     %- For browsers, the horizontal tab character is the smallest non-zero
0943     %- number of spaces necessary to line characters up along tab stops that are
0944     %- every 8 characters: behaviour obtained when n = 0.
0945     if n > 0
0946         str = strrep(str,sprintf('\t'),blanks(n));
0947     end

Generated at 19:47:41 15-Oct-2003 by m2html © 2003