Chris@381: @rem = '--*-Perl-*--'; Chris@381: @rem = ' Chris@381: @echo off Chris@381: perl -w -S %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9 Chris@381: goto endofperl Chris@381: @rem '; Chris@381: # perl -w -S %0.bat "$@" Chris@382: #!/usr/bin/perl Chris@381: # Chris@381: # mtree2html_2000 - produce html files from Matlab m-files. Chris@381: # use configuration file for flexibility Chris@381: # can process tree of directories Chris@381: # Chris@381: # Copyright (C) 1996-2000 Hartmut Pohlheim. All rights reserved. Chris@381: # includes small parts of m2html from Jeffrey C. Kantor 1995 Chris@381: # Chris@381: # Author: Hartmut Pohlheim Chris@381: # History: 06.03.1996 file created Chris@381: # 07.03.1996 first working version Chris@381: # 08.03.1996 modularized, help text only once included Chris@381: # 11.03.1996 clean up, some functions rwritten Chris@381: # 18.04.1996 silent output with writing in one line only Chris@381: # version 0.20 fixed Chris@381: # 14.05.1996 start of adding tree structure, could create tree Chris@381: # 15.05.1996 creating of index files for every directory Chris@381: # 17.05.1996 first working version except compact A-Z index Chris@381: # 20.05.1996 cleanup of actual version, more variables and Chris@381: # configurable settings Chris@381: # 21.05.1996 reading, update and creation of contents.m added Chris@381: # 22.05.1996 creation of short index started Chris@381: # 28.05.1996 jump letters for short index, Chris@381: # 3 different directory indexes (short/long/contents) Chris@381: # 29.05.1996 major cleanup, short and long index created from one function Chris@381: # links for HTML and Indexes from 1 function, Chris@381: # version 0.9 Chris@381: # 30.05.1996 contents.m changed to Contents.m (because unix likes it) Chris@381: # function definition can be in first line of m file before comments Chris@381: # version 0.91 fixed Chris@381: # 03.06.1996 contents file can be written as wanted, the links will be correct Chris@381: # cross references in help block of m-file will be found and Chris@381: # converted, even if the name of the function is written upper case Chris@381: # version 0.92 fixed Chris@381: # 05.06.1996 construction of dependency matrix changed, is able now to process Chris@381: # even the whole matlab tree (previous version needed to much memory) Chris@381: # removed warning for contents files in different directories Chris@381: # version 0.94 fixed Chris@381: # 06.06.1996 new link name matrices for ConstructHTMLFile created, Chris@381: # everything is done in ConstructDependencyMatrix, Chris@381: # both dependencies (calls and called) and matrix Chris@381: # with all mentioned names in this m-file, thus, much Chris@381: # less scanning in html construction Chris@381: # script is now (nearly) linear scalable, thus, matlab-toolbox Chris@381: # tree takes less than 1 hour on a Pentium120, with source Chris@381: # version 0.96 fixed Chris@381: # 10.06.1996 order of creation changed, first all indexes (includes Chris@381: # update/creation of contents.m) and then ConstructDepency Chris@381: # thus, AutoAdd section will be linked as well Chris@381: # excludenames extended, some more common word function names added Chris@381: # version 0.97 fixed Chris@381: # 17.02.1998 writecontentsm as command line parameter added Chris@381: # error of file not found will even appear when silent Chris@381: # version 1.02 Chris@381: # 21.05.2000 mark comments in source code specially (no fully correct, Chris@381: # can't handle % in strings) Chris@381: # version 1.11 Chris@381: # 05.11.2000 link also to upper and mixed case m-files Chris@381: # searching for .m files now really works (doesn't find grep.com any longer) Chris@381: # file renamed to mtree2html2001 Chris@381: # generated html code now all lower case Chris@381: # inclusion of meta-description and meta-keywords in html files Chris@381: # HTML4 compliance done (should be strict HTML4.0, quite near XHTML) Chris@381: # version 1.23 Chris@381: # Chris@383: # 29.03.2011 (Chris Cannam) add frames option. Chris@381: Chris@381: $VERSION = '1.23'; Chris@381: ($PROGRAM = $0) =~ s@.*/@@; $PROGRAM = "\U$PROGRAM\E"; chris@411: $debug = 1; Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # Define platform specific things Chris@381: #------------------------------------------------------------------------ Chris@381: # suffix for files to search is defined twice Chris@381: # the first ($suffix) is for string creation and contains the . as well Chris@381: # the second ($suffixforsearch) is for regular expression, handling of . is quite special Chris@381: $suffix = ".m"; Chris@381: $suffixforsearch = "m"; Chris@381: # the directory separator Chris@381: $dirsep = "/"; Chris@381: # what is the current directory Chris@381: $diract = "."; Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@382: # Define all variables and their standard settings Chris@381: # documentation of variables is contained in accompanying rc file Chris@381: #------------------------------------------------------------------------ Chris@381: %var = Chris@381: ( Chris@381: 'authorfile', '', Chris@381: 'codebodyfiles', '', Chris@381: 'codebodyindex', '', Chris@381: 'codeheadmeta', '', Chris@381: 'codehr', '
', Chris@381: 'codeheader', '', Chris@383: 'configfile', 'matlab-docs.conf', Chris@381: 'csslink', '', Chris@381: 'dirmfiles', $diract, Chris@381: 'dirhtml', $diract, Chris@381: 'exthtml', '.html', Chris@382: 'frames', 'yes', Chris@381: 'filenametopframe', 'index', Chris@381: 'filenameindexlongglobal', 'indexlg', Chris@381: 'filenameindexlonglocal', 'indexll', Chris@381: 'filenameindexshortglobal', 'indexsg', Chris@381: 'filenameindexshortlocal', 'indexsl', Chris@381: 'filenameextensionframe', 'f', Chris@381: 'filenameextensionindex', 'i', Chris@381: 'filenameextensionjump', 'j', Chris@381: 'filenamedirshort', 'dirtops', Chris@381: 'filenamedirlong', 'dirtopl', Chris@381: 'filenamedircontents', 'dirtopc', Chris@381: 'includesource', 'yes', Chris@381: 'links2filescase', 'all', Chris@381: 'processtree', 'yes', Chris@381: 'producetree', 'yes', Chris@381: 'textjumpindexlocal', 'Local Index', Chris@381: 'textjumpindexglobal', 'Global Index', Chris@381: 'texttitleframelayout', 'Documentation of Matlab Files', Chris@381: 'texttitleindexalldirs', 'Index of Directories', Chris@381: 'textheaderindexalldirs', 'Index of Directories', Chris@381: 'texttitleindex', '', Chris@381: 'textheaderindex', '', Chris@381: 'texttitlefiles', 'Documentation of ', Chris@381: 'textheaderfiles', 'Documentation of ', Chris@381: 'usecontentsm', 'yes', Chris@381: 'writecontentsm', 'no' Chris@381: ); Chris@381: Chris@381: Chris@381: # define all m-file names, that should be excluded from linking Chris@381: # however, files will still be converted Chris@381: @excludenames = ( 'all','ans','any','are', Chris@381: 'cs', Chris@381: 'demo','dos', Chris@381: 'echo','edit','else','elseif','end','exist', Chris@381: 'flag','for','function', Chris@381: 'global', Chris@381: 'help', Chris@381: 'i','if','inf','info', Chris@381: 'j', Chris@381: 'more', Chris@381: 'null', Chris@381: 'return', Chris@381: 'script','strings', Chris@381: 'what','which','while','who','whos','why', Chris@381: ); Chris@381: Chris@381: # Text for inclusion in created HTML/Frame files: Doctype and Charset Chris@381: $TextDocTypeHTML = ''; Chris@381: $TextDocTypeFrame = ''; Chris@381: $TextMetaCharset = ''; Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # Read the command line arguments Chris@381: #------------------------------------------------------------------------ Chris@381: if (@ARGV == 0) { Chris@381: &DisplayHelp() if &CheckFileName($var{'configfile'}, 'configuration file'); Chris@381: } Chris@381: Chris@381: # Print provided command line arguments on screen Chris@381: foreach (@ARGV) { print " $_\n "; } Chris@381: Chris@381: # Get the options Chris@381: use Getopt::Long; Chris@381: @options = ('help|h', 'todo|t', 'version|v', Chris@381: 'authorfile|a=s', 'configfile|c=s', 'dirhtml|html|d=s', Chris@381: 'dirmfiles|mfiles|m=s', 'includesource|i=s', Chris@381: 'processtree|r=s', 'producetree|p=s', Chris@381: 'silent|quiet|q', 'writecontentsm|w=s'); Chris@381: &GetOptions(@options) || die "use -h switch to display help statement\n"; Chris@381: Chris@381: Chris@381: # Display help or todo list, when requested Chris@381: &DisplayHelp() if $opt_help; Chris@381: &DisplayTodo() if $opt_todo; Chris@381: die "$PROGRAM v$VERSION\n" if $opt_version; Chris@381: Chris@381: $exit_status = 0; Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # Read the config file Chris@381: #------------------------------------------------------------------------ Chris@381: $var{'configfile'} = $opt_configfile if $opt_configfile; Chris@381: &GetConfigFile($var{'configfile'}); Chris@381: Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # Process/Check the command line otions Chris@381: #------------------------------------------------------------------------ Chris@381: $var{'dirhtml'} = $opt_dirhtml if $opt_dirhtml; Chris@381: if (!(substr($var{'dirhtml'}, -1, 1) eq $dirsep)) { $var{'dirhtml'} = $var{'dirhtml'}.$dirsep; } Chris@381: $var{'dirmfiles'} = $opt_dirmfiles if $opt_dirmfiles; Chris@381: if (!(substr($var{'dirmfiles'}, -1, 1) eq $dirsep)) { $var{'dirmfiles'} = $var{'dirmfiles'}.$dirsep; } Chris@381: Chris@381: $var{'authorfile'} = $opt_author if $opt_author; Chris@381: $var{'includesource'} = $opt_includesource if $opt_includesource; Chris@381: if ($var{'includesource'} ne 'no') { $var{'includesource'} = 'yes'; } Chris@381: $var{'processtree'} = $opt_processtree if $opt_processtree; Chris@381: if ($var{'processtree'} ne 'no') { $var{'processtree'} = 'yes'; } Chris@381: $var{'producetree'} = $opt_producetree if $opt_producetree; Chris@381: if ($var{'producetree'} ne 'no') { $var{'producetree'} = 'yes'; } Chris@381: if ($var{'processtree'} eq 'no') { $var{'producetree'} = 'no'; } Chris@382: if ($var{'frames'} ne 'no') { $var{'frames'} = 'yes'; } Chris@381: # if (($var{'processtree'} eq 'yes') && ($var{'producetree'} eq 'no')) { $var{'usecontentsm'} = 'no'; } Chris@381: Chris@381: $var{'writecontentsm'} = $opt_writecontentsm if $opt_writecontentsm; Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # Do the real stuff Chris@381: #------------------------------------------------------------------------ Chris@381: Chris@381: # Print variables on screen, when not silent Chris@381: &ListVariables if !$opt_silent; Chris@381: Chris@381: # Check the author file Chris@381: if ($var{'authorfile'} ne '') { chris@410: if (!($var{'authorfile'} =~ m,^/,)) { chris@410: # relative path: treat as relative to config file chris@410: my $cfd = $var{'configfile'}; chris@410: $cfd =~ s,/[^/]*$,/,; chris@410: $cfd =~ s,^[^/]*$,.,; chris@410: $var{'authorfile'} = "$cfd/" . $var{'authorfile'}; chris@410: } chris@410: if (&CheckFileName($var{'authorfile'}, 'author file')) { chris@410: $var{'authorfile'} = ''; chris@410: if (!$opt_silent) { print " Proceeding without author information!\n"; } chris@410: } Chris@381: } Chris@381: Chris@381: # Call the function doing all the real work Chris@381: &ConstructNameMatrix; Chris@381: Chris@381: &ConstructDependencyMatrix; Chris@381: Chris@381: &ConstructAllIndexFiles; Chris@381: Chris@381: &ConstructHTMLFiles; Chris@381: Chris@381: exit $exit_status; Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # Construct list of all mfile names and initialize various data arrays. Chris@381: #------------------------------------------------------------------------ Chris@381: sub ConstructNameMatrix Chris@381: { Chris@381: local(*MFILE); Chris@381: local($file, $dirname); Chris@381: local(@newdirectories); Chris@381: local(%localnames); Chris@381: Chris@381: $RecDeep = 0; Chris@381: &ParseTreeReadFiles($var{'dirmfiles'}, $RecDeep); Chris@381: Chris@381: foreach $dirname (@directories) { Chris@381: if ($dirnumbermfiles{$dirname} > 0) { Chris@381: push(@newdirectories, $dirname); Chris@381: if (! defined($contentsname{$dirname})) { Chris@381: $contentsname{$dirname} = 'Contents'; Chris@381: if (($var{'writecontentsm'} eq 'no') && ($var{'usecontentsm'} eq 'yes')) { Chris@381: print "\r ParseTree - for directory $dirname no contents file found!\n"; Chris@381: print " create one or enable writing of contents file (writecontentsm = yes)!\n"; Chris@381: } Chris@381: } Chris@381: } Chris@381: } Chris@381: @alldirectories = @directories; Chris@381: @directories = @newdirectories; Chris@381: Chris@381: foreach $dirname (@directories) { Chris@381: if ($debug > 0) { print "Dir: $dirname \t\t $dirnumbermfiles{$dirname} \t$contentsname{$dirname}\n"; } Chris@381: } Chris@381: Chris@381: @names = sort(keys %mfile); Chris@381: Chris@381: # check, if name of directory is identical to name of file Chris@381: @dirsinglenames = values(%dirnamesingle); Chris@381: grep($localnames{$_}++, @dirsinglenames); Chris@381: @dirandfilename = grep($localnames{$_}, @names); Chris@381: if (@dirandfilename) { Chris@381: print "\r Name clash between directory and file name: @dirandfilename\n"; Chris@381: print " These files will be excluded from linking!\n"; Chris@381: push(@excludenames, @dirandfilename); Chris@381: } Chris@381: Chris@381: # construct names matrix for help text linking Chris@381: # exclude some common words (and at the same time m-functions) from linking in help text Chris@381: grep($localnames{$_}++, @excludenames); Chris@381: @linknames = grep(!$localnames{$_}, @names); Chris@381: Chris@381: if ($debug > 2) { print "linknames (names of found m-files):\n @linknames\n"; } Chris@381: Chris@381: } Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # Parse tree and collect all Files Chris@381: #------------------------------------------------------------------------ Chris@381: sub ParseTreeReadFiles Chris@381: { Chris@381: local($dirname, $localRecDeep) = @_; Chris@381: local($file, $name, $filewosuffix); Chris@381: local($dirhtmlname, $dirmode); Chris@381: local($relpath, $relpathtoindex, $replacevardir); Chris@381: local(*CHECKDIR, *AKTDIR); Chris@381: local(@ALLEFILES); Chris@381: Chris@381: opendir(AKTDIR, $dirname) || die "ParseTree - Can't open directory $dirname: $!"; Chris@381: if ($debug > 1) { print "\nDirectory: $dirname\n"; } Chris@381: Chris@381: # create relative path Chris@381: $_ = $dirname; $replacevardir = $var{'dirmfiles'}; Chris@381: s/$replacevardir//; $relpath = $_; Chris@381: s/[^\/]+/../g; $relpathtoindex = $_; Chris@381: Chris@381: # producetree no Chris@381: if ($var{'producetree'} eq 'no') { $relpath = ''; $relpathtoindex = ''; } Chris@381: Chris@381: # names of directories (top-level and below top-level m-file-directory) Chris@381: push(@directories, $dirname); Chris@381: $dirnumbermfiles{$dirname} = 0; # set number of m-files for this dir to zero Chris@381: # relative path from top-level directory, depends on directory name Chris@381: $dirnamerelpath{$dirname} = $relpath; Chris@381: # relative path from actual directory to top-level directory, depends on directory name Chris@381: $dirnamerelpathtoindex{$dirname} = $relpathtoindex; Chris@381: # recursion level for directory, depends on directory name Chris@381: $dirnamerecdeep{$dirname} = $localRecDeep; Chris@381: Chris@381: # only the name of the directory, without path Chris@381: $rindexprint = rindex($dirname, $dirsep, length($dirname)-2); Chris@381: $rindsub = substr($dirname, $rindexprint+1, length($dirname)-$rindexprint-2); Chris@381: $dirnamesingle{$dirname} = $rindsub; Chris@381: Chris@381: # create name of html-directories Chris@381: $_ = $dirname; Chris@381: s/$var{'dirmfiles'}/$var{'dirhtml'}/; Chris@381: $dirhtmlname = $_; Chris@381: if ($var{'producetree'} eq 'no') { $dirhtmlname = $var{'dirhtml'}; } Chris@381: # try to open html directory, if error, then create directory, Chris@381: # use same mode as for corresponding m-file directory Chris@381: opendir(CHECKDIR,"$dirhtmlname") || do { Chris@381: $dirmode = (stat($dirname))[2]; # print "$dirmode\n"; Chris@381: mkdir("$dirhtmlname", $dirmode) || die ("Cannot create directory $dirhtmlname: $! !"); Chris@381: }; Chris@381: closedir(CHECKDIR); Chris@381: Chris@381: Chris@381: # read everything from this directory and process them Chris@381: @ALLEFILES = readdir(AKTDIR); Chris@381: Chris@381: foreach $file (@ALLEFILES) { Chris@381: # exclude . and .. directories Chris@381: next if $file eq '.'; next if $file eq '..'; Chris@381: Chris@381: # test for existense of entry (redundant, used for debugging) Chris@381: if (-e $dirname.$file) { Chris@381: # if it's a directory, call this function recursively Chris@381: if (-d $dirname.$file) { Chris@381: if ($var{'processtree'} eq 'yes') { Chris@381: &ParseTreeReadFiles($dirname.$file.$dirsep, $localRecDeep+1); Chris@381: } Chris@381: } Chris@381: # if it's a file - test for m-file, save name and create some arrays Chris@381: elsif (-f $dirname.$file) { Chris@381: if ($file =~ /\.$suffixforsearch$/i) { Chris@381: # Remove the file suffix to establish the matlab identifiers Chris@381: $filewosuffix = $file; Chris@381: $filewosuffix =~ s/\.$suffixforsearch$//i; Chris@381: # $filename = $name; Chris@381: Chris@381: # Contents file in unix must start with a capital letter (Contents.m) Chris@381: # ensure, that m-file name is lower case, except the contents file Chris@381: if (! ($filewosuffix =~ /^contents$/i)) { chris@388: # if ($var{'links2filescase'} eq 'low') { $filewosuffix = "\L$filewosuffix\E"; } Chris@381: $filewosuffixlow = "\L$filewosuffix\E"; Chris@381: } Chris@381: else { $contentsname{$dirname} = $filewosuffix; } Chris@381: Chris@381: # internal handle name is always lower case Chris@381: $name = $filewosuffixlow; Chris@381: # file name is not lower case Chris@381: $filename = $filewosuffix; Chris@381: Chris@381: # if don't use C|contents.m, then forget all C|contents.m Chris@381: if ($var{'usecontentsm'} eq 'no') { if ($name =~ /contents/i) { next; } } Chris@381: Chris@381: # if m-file with this name already exists, use directory and name for name Chris@381: # only the first occurence of name will be used for links Chris@381: if (defined $mfile{$name}) { Chris@381: if (! ($name =~ /^contents$/i) ) { Chris@381: print "\r ParseTree - Name conflict: $name in $dirname already exists: $mfile{$name} !\n"; Chris@381: print " $mfile{$name} will be used for links!\n"; Chris@381: } Chris@381: $name = $dirname.$name; Chris@381: } Chris@381: # mfile name with path Chris@381: $mfile{$name} = $dirname.$file; Chris@381: # mfile name (without path) Chris@381: $mfilename{$name} = $filename; Chris@381: # mfile directory Chris@381: $mfiledir{$name} = $dirname; Chris@381: Chris@381: # html file name and full path, special extension of Contents files Chris@381: if ($name =~ /contents/i) { $extrahtmlfilename = $dirnamesingle{$dirname}; } Chris@381: else { $extrahtmlfilename = ''; } Chris@381: $hfile{$name} = $dirhtmlname.$mfilename{$name}.$extrahtmlfilename.$var{'exthtml'}; Chris@381: Chris@381: # save relative html path Chris@381: # if ($var{'producetree'} eq 'yes') { Chris@381: $hfilerelpath{$name} = $relpath; Chris@381: # } else { # if no tree to produce, relative path is empty Chris@381: # $hfilerelpath{$name} = ''; Chris@381: # } Chris@381: Chris@381: # create relative path from html file to directory with global index file Chris@381: $hfileindexpath{$name} = $relpathtoindex; Chris@381: Chris@381: # Function declaration, if one exists, set default to script Chris@381: $synopsis{$name} = ""; Chris@381: $mtype{$name} = "script"; Chris@381: Chris@381: # First comment line Chris@381: $apropos{$name} = ""; Chris@381: Chris@381: # count number of m-files in directories Chris@381: $dirnumbermfiles{$dirname}++; Chris@381: Chris@381: if ($debug > 1) { Chris@381: if ($opt_silent) { print "\r"; } Chris@381: print " ParseTree: $name \t\t $mfile{$name} \t\t $hfile{$name}\t\t"; Chris@381: if (!$opt_silent) { print "\n"; } Chris@381: } Chris@381: } Chris@381: } Chris@381: else { Chris@381: print "Unknown type of file in $dirname: $file\n"; Chris@381: } Chris@381: } Chris@381: else { print "Error: Not existing file in $dirname: $file\n"; } Chris@381: } Chris@381: Chris@381: closedir(AKTDIR) Chris@381: Chris@381: } Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # Construct Dependency matrix Chris@381: # $dep{$x,$y} > 0 if $x includes a reference to $y. Chris@381: #------------------------------------------------------------------------ Chris@381: sub ConstructDependencyMatrix Chris@381: { Chris@381: &ConstructDependencyMatrixReadFiles('all'); Chris@381: &ConstructDependencyMatrixReally; Chris@381: } Chris@381: Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # Construct Dependency matrix Chris@381: # $dep{$x,$y} > 0 if $x includes a reference to $y. Chris@381: #------------------------------------------------------------------------ Chris@381: sub ConstructDependencyMatrixReadFiles Chris@381: { Chris@381: local($whatstring) = @_; Chris@381: local(*MFILE); Chris@381: local($name, $inames); Chris@381: local(%symbolsdep, %symbolsall); Chris@381: Chris@381: # Initialize as all zeros. Chris@381: # foreach $name (@names) { grep($dep{$name,$_}=0,@names); if ($debug > 0) { print "\r DepMatrix anlegen: $name\t$#names\t"; } } Chris@381: Chris@381: # Compute the dependency matrix Chris@381: $inames = -1; Chris@381: foreach $name (@names) { Chris@381: # Read each file and tabulate the distinct alphanumeric identifiers in Chris@381: # an array of symbols. Also scan for: Chris@381: # synopsis: The function declaration line Chris@381: # apropos: The first line of the help text Chris@381: Chris@381: # look for whatstring, if all: process every file, if contents: process only contents files Chris@381: if ($whatstring eq 'contents') { if (! ($name =~ /contents$/i) ) { next; } } Chris@381: elsif ($whatstring eq 'all') { } # do nothing Chris@381: else { print "\r ConstructDependency: Unknown parameter whatstring: $whatstring \n"; } Chris@381: Chris@381: undef %symbolsall; undef %symbolsdep; Chris@381: open(MFILE,"<$mfile{$name}") || die("Can't open $mfile{$name}: $!\n"); Chris@381: while () { Chris@381: chop; Chris@381: Chris@381: # Split on nonalphanumerics, then look for all words, used for links later Chris@381: # this one for all references Chris@381: @wordsall = grep(/[a-zA-Z]\w*/, split('\W',$_)); Chris@381: # set all words to lower case for link checking Chris@381: undef @wordsall2; Chris@381: # do case conversion not, case checking is done later Chris@381: foreach (@wordsall) { push(@wordsall2, "\L$_\E"); } Chris@381: # @wordsall2 = @wordsall; Chris@381: grep($symbolsall{$_}++, @wordsall2); Chris@381: Chris@381: # Store first comment line, skip all others. Chris@381: if (/^\s*%/) { Chris@381: if (!$apropos{$name}) { Chris@381: s/^\s*%\s*//; # remove % and leading white spaces on line Chris@381: $_ = &SubstituteHTMLEntities($_); Chris@381: $apropos{$name} = $_; Chris@381: } Chris@381: next; Chris@381: } Chris@381: Chris@381: # If it's the function declaration line, then store it and skip Chris@381: # but only, when first function definition (multiple function lines when private subfunctions in file Chris@381: if ($synopsis{$name} eq '') { Chris@381: if (/^\s*function/) { Chris@381: s/^\s*function\s*//; Chris@381: $synopsis{$name} = $_; Chris@381: $mtype{$name} = "function"; Chris@381: next; Chris@381: } Chris@381: } Chris@381: Chris@381: # Split off any trailing comments Chris@381: if ($_ ne '') { Chris@381: # this one for references in program code only Chris@381: # when syntax parsing, here is a working place Chris@381: ($statement) = split('%',$_,1); Chris@381: @wordsdep = grep(/[a-zA-Z]\w*/,split('\W',$statement)); Chris@381: # do case conversion not, case checking is done later Chris@381: undef @wordsdep2; Chris@381: foreach (@wordsdep) { push(@wordsdep2, "\L$_\E"); } Chris@381: grep($symbolsdep{$_}++, @wordsdep2); Chris@381: } Chris@381: } Chris@381: close MFILE; Chris@381: Chris@381: # compute intersection between %symbolsall and @linknames Chris@381: delete($symbolsall{$name}); Chris@381: # foreach $localsumall ($symbolsall) { Chris@381: # $localsumall = "\L$localsumall\E"; Chris@381: # } Chris@381: @{'all'.$name} = grep($symbolsall{$_}, @linknames); Chris@381: Chris@381: # compute intersection between %symbolsdep and @linknames Chris@381: delete($symbolsdep{$name}); Chris@381: @{'depcalls'.$name} = grep($symbolsdep{$_}, @linknames); Chris@381: Chris@381: $inames++; print "\r DepCallsMatrix: $inames/$#names\t $name\t"; Chris@381: if ($debug > 2) { print "\n depnames: @{'depcalls'.$name}\n all: @{'all'.$name}\n"; } Chris@381: } Chris@381: } Chris@381: Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # Construct Dependency matrix Chris@381: # $dep{$x,$y} > 0 if $x includes a reference to $y. Chris@381: #------------------------------------------------------------------------ Chris@381: sub ConstructDependencyMatrixReally Chris@381: { Chris@381: local($inames, $name); Chris@381: Chris@381: $inames = -1; Chris@381: foreach $name (@names) { undef %{'depint'.$name}; } Chris@381: foreach $name (@names) { Chris@381: grep(${'depint'.$_}{$name}++, @{'depcalls'.$name}); Chris@381: $inames++; print "\r DepCalledMatrix1: $inames/$#names\t $name\t"; Chris@381: } Chris@381: $inames = -1; Chris@381: foreach $name (@names) { Chris@381: # compute intersection between %depint.name{$_} and @linknames Chris@381: if (defined (%{'depint'.$name})) { @{'depcalled'.$name} = grep(${'depint'.$name}{$_}, @linknames); } Chris@381: $inames++; print "\r DepCalledMatrix2: $inames/$#names\t $name\t"; Chris@381: if ($debug > 2) { print "\n depcalled: @{'depcalled'.$name}\n"; } Chris@381: } Chris@381: Chris@381: } Chris@381: Chris@381: Chris@381: #======================================================================== Chris@381: # Construct all index files Chris@381: #======================================================================== Chris@381: sub ConstructAllIndexFiles Chris@381: { Chris@381: local(@localnames); Chris@381: local($ActDir); Chris@381: local($name); Chris@381: Chris@381: # define variables and names for frame target Chris@381: $GlobalNameFrameMainLeft = 'Cont_Main'; Chris@381: $GlobalNameFrameMainRight = 'Cont_Lower'; Chris@381: $GlobalNameFrameAZIndexsmall = 'IndexAZindex'; Chris@381: $GlobalNameFrameAZIndexjump = 'IndexAZjump'; Chris@381: Chris@381: $indexcreated = 0; Chris@381: Chris@381: &ConstructHighestIndexFile; Chris@381: $indexcreated++; Chris@381: Chris@381: # if ($var{'producetree'} eq 'yes') { Chris@381: # moved next 2 lines out of if for producetree no Chris@381: # &ConstructHighestIndexFile; Chris@381: # $indexcreated++; Chris@381: Chris@381: foreach $ActDir (@directories) { Chris@381: undef @localnames; Chris@381: foreach $name (@names) { Chris@381: local($pathsubstr) = substr($mfile{$name}, 0, rindex($mfile{$name}, "/")+1); Chris@381: if ($ActDir eq $pathsubstr) { Chris@381: if ($debug > 1) { print "IndexFile: $pathsubstr ActDir: $ActDir Hfilerelpath: $hfilerelpath{$name}\n"; } Chris@381: push(@localnames, $name); Chris@381: } Chris@381: } Chris@381: if ($debug > 2) { print "localnames: @localnames\n"; } Chris@381: # create contents file and short|long index of files in local directory Chris@381: &ConstructContentsmFile($ActDir, @localnames); Chris@381: &ConstructAZIndexFile($ActDir, 'short', 'local', @localnames); Chris@381: &ConstructAZIndexFile($ActDir, 'long', 'local', @localnames); Chris@381: $indexcreated+=2; Chris@381: } Chris@381: # } else { Chris@381: # &ConstructContentsmFile($var{'dirmfiles'}, @names); Chris@381: # } Chris@381: Chris@381: # create short|long index of files in all directory Chris@381: &ConstructAZIndexFile($var{'dirmfiles'}, 'short', 'global', @names); Chris@381: &ConstructAZIndexFile($var{'dirmfiles'}, 'long', 'global', @names); Chris@381: $indexcreated+=2; Chris@381: Chris@381: # if contents.m were created or updated, the dependency matrices should Chris@381: # be updated as well Chris@381: if ($var{'writecontentsm'} eq 'yes') { &ConstructDependencyMatrixReadFiles('contents');; } Chris@381: } Chris@381: Chris@381: Chris@381: #======================================================================== Chris@381: # Construct the highest level index file Chris@381: #======================================================================== Chris@381: sub ConstructHighestIndexFile Chris@381: { Chris@381: local(*IFILE); Chris@381: local($indexfile, $filename); Chris@381: Chris@381: # Build the frame layout file, this files includes the layout of the frames Chris@381: # Build the frame layout file name (highest one) Chris@381: $indexfile = $var{'dirhtml'}.$var{'filenametopframe'}.$var{'exthtml'}; Chris@381: Chris@382: if ($var{'frames'} eq 'yes') { Chris@381: Chris@382: open(IFILE,">$indexfile") || die("Cannot open frame layout file $indexfile\n"); Chris@381: Chris@382: # Write the header of frame file Chris@382: print IFILE "$TextDocTypeFrame\n\n\n$var{'codeheadmeta'}\n$TextMetaCharset\n"; Chris@382: print IFILE " $var{'texttitleframelayout'}\n"; Chris@382: print IFILE "\n"; Chris@381: Chris@382: # definition of 2 frames, left the tree of directories, Chris@382: # right the index of that directory or the docu of a file Chris@382: print IFILE "\n"; Chris@382: print IFILE " \n"; Chris@382: print IFILE " \n"; print IFILE "\n"; Chris@381: Chris@382: print IFILE "\n"; Chris@382: Chris@382: close(IFILE); Chris@382: Chris@382: if ($opt_silent) { print "\r"; } Chris@382: print " Frame layout file created: $indexfile\t"; Chris@382: if (!$opt_silent) { print "\n"; } Chris@382: } Chris@381: Chris@381: for($irun=0; $irun <= 2; $irun++) { Chris@381: # Build the top directory index file, these files include the directory tree Chris@381: # Build the directory tree index file name Chris@381: Chris@381: # Create no directory file for contents, when no contents to use Chris@381: if (($irun == 2) && ($var{'usecontentsm'} eq 'no')) { next; } Chris@381: Chris@381: # Assign the correct index file name Chris@381: if ($irun == 0) { $filename = $var{'filenamedirshort'}; } Chris@381: elsif ($irun == 1) { $filename = $var{'filenamedirlong'}; } Chris@381: elsif ($irun == 2) { $filename = $var{'filenamedircontents'}; } Chris@381: Chris@381: $indexfile = $var{'dirhtml'}.$filename.$var{'exthtml'}; Chris@381: Chris@381: open(IFILE,">$indexfile") || die("Cannot open directory tree index file $indexfile\n"); Chris@381: # Write header of HTML file Chris@381: print IFILE "$TextDocTypeHTML\n\n\n$var{'codeheadmeta'}\n$TextMetaCharset\n$var{'csslink'}\n"; Chris@381: Chris@381: if ($var{'texttitleindexalldirs'} eq '') { Chris@381: print IFILE "Index of Directories of $var{'dirmfiles'}\n"; Chris@381: } else { Chris@381: print IFILE "$var{'texttitleindexalldirs'}\n"; Chris@381: } Chris@382: Chris@382: if ($var{'frames'} eq 'yes') { Chris@382: print IFILE "\n"; Chris@382: } Chris@382: Chris@381: print IFILE "\n"; Chris@381: print IFILE "\n"; chris@410: print IFILE "
\n"; Chris@381: if ($var{'textheaderindexalldirs'} eq '') { Chris@381: print IFILE "

Index of Directories of $var{'dirmfiles'}

\n"; Chris@381: } else { Chris@381: print IFILE "

$var{'textheaderindexalldirs'}

\n"; Chris@381: } chris@389: print IFILE "

\n"; Chris@382: Chris@382: if ($var{'frames'} eq 'yes') { Chris@382: if ($irun == 0) { print IFILE "short\n"; } Chris@382: else { print IFILE "short\n"; } Chris@382: if ($irun == 1) { print IFILE " | long\n"; } Chris@382: else { print IFILE " | long\n"; } Chris@382: if ($var{'usecontentsm'} eq 'yes') { Chris@382: if ($irun == 2) { print IFILE " | contents\n"; } Chris@382: else { print IFILE " | contents\n"; } Chris@382: } Chris@382: } else { Chris@382: if ($irun == 0) { print IFILE "short\n"; } Chris@382: else { print IFILE "short\n"; } Chris@382: if ($irun == 1) { print IFILE " | long\n"; } Chris@382: else { print IFILE " | long\n"; } Chris@382: if ($var{'usecontentsm'} eq 'yes') { Chris@382: if ($irun == 2) { print IFILE " | contents\n"; } Chris@382: else { print IFILE " | contents\n"; } Chris@382: } Chris@381: } Chris@381: Chris@381: print IFILE "


\n\n"; Chris@381: print IFILE "\n"; } Chris@381: print IFILE "\n
$var{'codehr'}\n"; Chris@381: Chris@381: # Include info about author from authorfile Chris@381: &WriteFile2Handle($var{'authorfile'}, IFILE); Chris@381: Chris@381: print IFILE "\n"; Chris@381: print IFILE "\n"; chris@410: print IFILE "
\n\n\n"; Chris@381: Chris@381: close(IFILE); Chris@381: Chris@381: if ($opt_silent) { print "\r"; } Chris@381: print " Directory - Indexfile created: $indexfile\t"; Chris@381: if (!$opt_silent) { print "\n"; } Chris@381: } Chris@381: } Chris@381: Chris@381: Chris@381: #======================================================================== Chris@381: # Construct the A-Z index file (global/local and/or short/long) Chris@381: #======================================================================== Chris@381: sub ConstructAZIndexFile Chris@381: { Chris@381: local($LocalActDir, $LocalShortLong, $LocalGlobalLocal, @localnames) = @_; Chris@381: local(*IFILE); Chris@381: local($name, $indexfilename, $dirpath); Chris@381: local($firstletter, $firstone); Chris@381: Chris@381: if ($debug > 2) { print "localnames in AZ small: @localnames\n"; print " ActDir in A-Z: $LocalActDir\n"; } Chris@381: Chris@381: # extract filename of index file from parameters of function Chris@381: if ($LocalShortLong eq 'short') { Chris@381: if ($LocalGlobalLocal eq 'global') { $indexfilename = $var{'filenameindexshortglobal'}; } Chris@381: elsif ($LocalGlobalLocal eq 'local') { $indexfilename = $var{'filenameindexshortlocal'}; } Chris@381: else { die "wrong parameter for LocalGlobalLocal in ConstructAZIndexFile: $LocalGlobalLocal."; } Chris@381: } elsif ($LocalShortLong eq 'long') { Chris@381: if ($LocalGlobalLocal eq 'global') { $indexfilename = $var{'filenameindexlongglobal'}; } Chris@381: elsif ($LocalGlobalLocal eq 'local') { $indexfilename = $var{'filenameindexlonglocal'}; } Chris@381: else { die "wrong parameter for LocalGlobalLocal in ConstructAZIndexFile: $LocalGlobalLocal."; } Chris@381: } else { die "wrong parameter for LocalShortLong in ConstructAZIndexFile: $LocalShortLong."; } Chris@381: Chris@381: # producetree no Chris@381: # if ($var{'producetree'} eq 'no') { $dirnamehere = ''; } Chris@381: # else { $dirnamehere = '$dirnamerelpath{$LocalActDir}'; } Chris@381: # Build the index file name Chris@381: # handle the global index file case separately (no extra directory name in file) Chris@381: # the local index file name must be extended by the name of the directory Chris@381: if ($LocalGlobalLocal eq 'global') { $extradirfilename = ''; } Chris@381: else { $extradirfilename = $dirnamesingle{$LocalActDir}; } Chris@381: $indexfile = $var{'dirhtml'}.$dirnamerelpath{$LocalActDir}.$indexfilename.$var{'filenameextensionindex'}.$extradirfilename.$var{'exthtml'}; Chris@382: chris@401: if ($LocalShortLong eq 'short' and $extradirfilename eq '' and $var{'frames'} ne 'yes') { chris@401: # With no frames and no subdir path, this must go in the chris@401: # top-level index file instead Chris@382: $indexfile = $var{'dirhtml'}.$var{'filenametopframe'}.$var{'exthtml'}; Chris@382: } Chris@382: Chris@381: if ($debug > 2) { print " indexfilename (a-z small): $indexfile\n"; } Chris@381: Chris@381: open(IFILE,">$indexfile") || die("Cannot open index file $indexfile: $!\n"); Chris@381: Chris@381: # Write the header of HTML file Chris@381: print IFILE "$TextDocTypeHTML\n\n\n$var{'codeheadmeta'}\n$TextMetaCharset\n$var{'csslink'}\n"; Chris@381: chris@410: my $dirToPrint = $LocalActDir; chris@410: $dirToPrint =~ s,^./,,; chris@410: Chris@381: if ($var{'texttitleindex'} eq '') { chris@410: print IFILE "Index of Matlab Files in Directory $dirToPrint\n"; Chris@381: } else { Chris@381: if ($LocalGlobalLocal eq 'global') { print IFILE "$var{'texttitleindex'}\n"; } chris@410: else { print IFILE "$var{'texttitleindex'} in Directory $dirToPrint\n"; } Chris@381: } Chris@382: Chris@382: if ($var{'frames'} eq 'yes') { Chris@382: print IFILE "\n"; Chris@382: } Chris@381: print IFILE "\n"; Chris@382: Chris@381: print IFILE "\n"; chris@410: print IFILE "
\n"; Chris@381: if ($var{'textheaderindex'} eq '') { chris@410: print IFILE "

Index of Matlab Files in Directory $dirToPrint

\n"; Chris@381: } else { Chris@381: if ($LocalGlobalLocal eq 'global') { print IFILE "

$var{'textheaderindex'}

\n"; } chris@410: else { print IFILE "

$var{'textheaderindex'} in Directory $dirToPrint

\n"; } Chris@381: } Chris@381: Chris@381: # include links to indexes Chris@381: &ConstructLinks2Index(IFILE, $dirnamerelpathtoindex{$LocalActDir}, $LocalActDir, $LocalGlobalLocal); Chris@381: Chris@381: # Collect the starting letters of m files in this directory or all m-files Chris@381: for('a'..'z') { undef @{$_}; } Chris@381: foreach $name (@localnames) { Chris@381: if (! ($mfilename{$name} =~ /contents/i)) { Chris@381: $firstletter = substr($mfilename{$name}, 0, 1); Chris@381: # convert first letter always to lower case Chris@381: # needed for reference to lower and upper case m-files Chris@381: $firstletter = "\L$firstletter\E"; Chris@381: push(@{$firstletter}, $name); Chris@381: } Chris@381: } Chris@381: Chris@381: if ($LocalShortLong eq 'short') { Chris@381: # begin create short index Chris@381: print IFILE "\n"; Chris@381: Chris@381: for('a'..'z') { Chris@381: # print " $_: @{$_}\n"; Chris@381: $numberofletter = $#{$_}+1; chris@410: $cols = 3; Chris@381: if ($numberofletter > 0) { chris@410: print IFILE "\n\n"; chris@410: for ($count = 0; $count < $numberofletter; $count++) { chris@410: if (($count % $cols) == 0) { chris@410: if ($count > 0) { chris@410: print IFILE "\n"; chris@410: } chris@410: print IFILE ""; chris@410: } chris@410: $name = @{$_}[$count]; chris@410: if ($LocalGlobalLocal eq 'global') { $dirpath = $hfilerelpath{$name}; } else { $dirpath = ""; } chris@410: print IFILE ""; chris@410: } chris@410: chris@410: print IFILE "\n"; chris@410: chris@410: # $numberhalf = ($numberofletter + 1 - (($numberofletter+1) % 2))/2; chris@410: # if ($debug > 2) { print " $_: @{$_} \t $numberhalf \t $numberofletter\n"; } chris@410: # for($count = 0; $count < $numberhalf; $count++) { chris@410: # $name = @{$_}[$count]; chris@410: # if ($LocalGlobalLocal eq 'global') { $dirpath = $hfilerelpath{$name}; } else { $dirpath = ""; } chris@410: # print IFILE ""; chris@410: # if (($count + $numberhalf) < $numberofletter) { chris@410: # $name = @{$_}[$count + $numberhalf]; chris@410: # if ($LocalGlobalLocal eq 'global') { $dirpath = $hfilerelpath{$name}; } else { $dirpath = ""; } chris@410: # print IFILE "\n"; chris@410: # } else { chris@410: # print IFILE "\n"; chris@410: # } chris@410: # } Chris@381: } Chris@381: } Chris@381: print IFILE "

\U$_\E
$mfilename{$name}
$mfilename{$name}$mfilename{$name}
\n
$var{'codehr'}\n"; Chris@381: Chris@381: } elsif ($LocalShortLong eq 'long') { Chris@381: # begin create long index chris@410: print IFILE "\n"; chris@401: print IFILE "\n"; Chris@381: Chris@381: for('a'..'z') { Chris@381: # print " $_: @{$_}\n"; Chris@381: $numberofletter = $#{$_}+1; Chris@381: if ($numberofletter > 0) { Chris@381: $firstone = 1; Chris@381: foreach $name (@{$_}) { Chris@381: if ($debug > 1) { print " AZinforeach1: $name \t\t $hfilerelpath{$name} \t\t $dirnamerelpath{$LocalActDir}\n"; } Chris@381: if ($LocalGlobalLocal eq 'global') { $dirpath = $hfilerelpath{$name}; } else { $dirpath = ""; } Chris@381: if (! ($mfilename{$name} =~ /contents/i)) { chris@400: if ($firstone == 1) { print IFILE "\n\n"; $firstone = 0; } Chris@381: print IFILE "\n"; Chris@381: } Chris@381: } Chris@381: } Chris@381: } Chris@381: print IFILE "
NameSynopsis

\U$_\E
$mfilename{$name}$apropos{$name}
\n
$var{'codehr'}\n"; Chris@381: } else { die "wrong parameter for LocalShortLong in ConstructAZIndexFile: $LocalShortLong."; } Chris@381: Chris@381: # Include info about author from authorfile Chris@381: &WriteFile2Handle($var{'authorfile'}, IFILE); Chris@381: Chris@381: print IFILE "\n"; Chris@381: print IFILE "\n"; chris@410: print IFILE "
\n\n\n"; Chris@381: Chris@381: close(IFILE); Chris@381: Chris@381: if ($opt_silent) { print "\r"; } Chris@381: print " Indexfile small (A-Z) created: $indexfile\t"; Chris@381: if (!$opt_silent) { print "\n"; } Chris@381: Chris@381: Chris@381: # Build the A-Z jump index file name Chris@381: # handle the global index file case separately (no extra directory name in file) Chris@381: if ($LocalGlobalLocal eq 'global') { $extradirfilename = ''; } Chris@381: else { $extradirfilename = $dirnamesingle{$LocalActDir}; } Chris@381: Chris@382: if ($var{'frames'} eq 'yes') { Chris@382: Chris@382: $indexfile = $var{'dirhtml'}.$dirnamerelpath{$LocalActDir}.$indexfilename.$var{'filenameextensionjump'}.$extradirfilename.$var{'exthtml'}; Chris@382: if ($debug > 2) { print " indexfilename (a-z jump): $indexfile\n"; } Chris@382: open(IFILE,">$indexfile") || die("Cannot open jump index file $indexfile: $!\n"); Chris@382: Chris@382: # Write the header of HTML file Chris@382: print IFILE "$TextDocTypeHTML\n\n\n$var{'codeheadmeta'}\n$TextMetaCharset\n$var{'csslink'}\n"; Chris@382: Chris@382: if ($var{'texttitleindex'} eq '') { chris@410: print IFILE "A-Z jump index in directory $dirToPrint\n"; Chris@382: } else { Chris@382: if ($LocalGlobalLocal eq 'global') { print IFILE "$var{'texttitleindex'}\n"; } chris@410: else { print IFILE "$var{'texttitleindex'} in Directory $dirToPrint\n"; } Chris@382: } Chris@382: Chris@382: if ($var{'frames'} eq 'yes') { Chris@382: print IFILE "\n"; Chris@382: } Chris@382: print IFILE "\n"; Chris@382: print IFILE "\n"; chris@410: print IFILE "
\n"; Chris@382: Chris@382: # Write the A-Z jump line, generate link for letters with files starting with this letter Chris@382: # and only letters for no files starting with this letter Chris@382: # use previously generated arrays with names of files sorted by starting letter Chris@382: for('a'..'z') { Chris@382: $numberofletter = $#{$_}+1; Chris@382: if ($numberofletter > 0) { Chris@382: print IFILE "\U$_\E \n"; Chris@382: } else { Chris@382: print IFILE "\U$_\E \n"; Chris@382: } Chris@382: } Chris@382: chris@410: print IFILE "
\n\n"; Chris@382: Chris@382: close(IFILE); Chris@382: Chris@382: if ($opt_silent) { print "\r"; } Chris@382: print " Indexfile small (A-Z jump) created: $indexfile\t"; Chris@382: if (!$opt_silent) { print "\n"; } Chris@381: } Chris@381: Chris@381: Chris@381: # Build the frame layout file, this file includes the layout of the frames Chris@381: # Build the frame layout file name (for small/compact A-Z index) Chris@381: # handle the global index file case separately (no extra directory name in file) Chris@381: if ($LocalGlobalLocal eq 'global') { $extradirfilename = ''; } Chris@381: else { $extradirfilename = $dirnamesingle{$LocalActDir}; } Chris@381: Chris@382: if ($var{'frames'} eq 'yes') { Chris@381: Chris@382: $indexfile = $var{'dirhtml'}.$dirnamerelpath{$LocalActDir}.$indexfilename.$var{'filenameextensionframe'}.$extradirfilename.$var{'exthtml'}; Chris@382: if ($debug > 2) { print " indexfilename (a-z frame): $indexfile\n"; } Chris@381: Chris@382: open(IFILE,">$indexfile") || die("Cannot open jump index frame file $indexfile: $!\n"); Chris@382: Chris@382: # Write the header of Frame file Chris@382: print IFILE "$TextDocTypeHTML\n\n\n$var{'codeheadmeta'}\n$TextMetaCharset\n$var{'csslink'}\n"; Chris@382: Chris@382: if ($var{'texttitleindex'} eq '') { chris@410: print IFILE "Index of Matlab Files in Directory $dirToPrint\n"; Chris@382: } else { Chris@382: if ($LocalGlobalLocal eq 'global') { print IFILE "$var{'texttitleindex'}\n"; } chris@410: else { print IFILE "$var{'texttitleindex'} in Directory $dirToPrint\n"; } Chris@382: } Chris@382: print IFILE "\n"; Chris@382: Chris@382: # definition of 2 frames, top the A-Z index, below the jump letter line Chris@382: print IFILE "\n"; Chris@382: print IFILE " \n"; Chris@382: print IFILE " \n"; Chris@382: print IFILE "\n"; Chris@382: Chris@382: print IFILE "\n"; Chris@382: Chris@382: close(IFILE); Chris@382: Chris@382: if ($opt_silent) { print "\r"; } Chris@382: print " Frame layout file created: $indexfile\t"; Chris@382: if (!$opt_silent) { print "\n"; } Chris@381: } Chris@381: } Chris@382: Chris@381: Chris@381: #======================================================================== Chris@381: # Construct the links to all indexes Chris@381: #======================================================================== Chris@381: sub ConstructLinks2Index Chris@381: { Chris@381: local(*WRITEFILE, $LocalPath2Index, $PathContents, $LocalGlobalLocal) = @_; Chris@381: Chris@381: # include links to short/long - local/global index and C|contents.m chris@389: print WRITEFILE "\n

"; chris@389: print WRITEFILE "$var{'textjumpindexglobal'} "; Chris@382: Chris@382: if ($var{'frames'} eq 'yes') { Chris@382: print WRITEFILE "short | "; chris@389: print WRITEFILE "long\n"; Chris@382: } else { Chris@387: print WRITEFILE "short | "; chris@389: print WRITEFILE "long\n"; Chris@382: } Chris@382: Chris@381: if ($LocalGlobalLocal eq 'local') { Chris@381: if ($var{'usecontentsm'} eq 'yes') { Chris@381: print WRITEFILE " | Local contents\n"; Chris@381: } chris@389: if ($var{'frames'} eq 'yes') { chris@389: print WRITEFILE " | $var{'textjumpindexlocal'} "; Chris@382: print WRITEFILE "short | "; chris@389: print WRITEFILE "long\n"; chris@389: } else { chris@389: print WRITEFILE " | $var{'textjumpindexlocal'} "; chris@389: print WRITEFILE "short | "; chris@389: print WRITEFILE "long\n"; chris@389: } Chris@381: } Chris@381: print WRITEFILE "

\n\n"; Chris@381: print WRITEFILE "$var{'codehr'}\n"; Chris@381: } Chris@381: Chris@381: Chris@381: #======================================================================== Chris@381: # Construct the contents.m files or update Chris@381: #======================================================================== Chris@381: sub ConstructContentsmFile Chris@381: { Chris@381: local($LocalActDir, @localnames) = @_; Chris@381: local(*CFILE, $name,$newline); Chris@381: local($contentsfile, $isincontentsonly); Chris@381: local(@lines, @autoaddlines, @emptylines); Chris@381: local($autoadd) = 'AutoAdd'; Chris@381: local($autoaddsection) = 0; Chris@381: local($emptylineflag) = 0; Chris@381: local(%nameincontents); Chris@381: Chris@381: # Build the contents file name Chris@381: $contentsfile = $LocalActDir.$contentsname{$LocalActDir}.$suffix; Chris@381: Chris@381: if (-e $contentsfile) { Chris@381: open(CFILE,"<$contentsfile") || die("Cannot open contents file $contentsfile: $!\n"); Chris@381: while () { Chris@381: # Search for the specified string pattern Chris@381: @words = split; Chris@381: if ((@words >= 3) && ($words[2] eq '-')) { Chris@381: $isincontentsonly = 0; Chris@381: foreach $name (@localnames) { Chris@381: if ($name eq $words[1]) { # old Chris@381: # if ($mfilename{$name} eq $words[1]) { Chris@381: $isincontentsonly = 1; Chris@381: $nameincontents{$name} = 1; Chris@381: $newline = sprintf("%% %-13s - %s\n", $mfilename{$name}, $apropos{$name}); Chris@381: push(@lines, $newline); Chris@381: } Chris@381: } Chris@381: # issue a warning, if file is in contents, but not as file in the directory Chris@381: if ($isincontentsonly == 0) { Chris@381: print "\rConstructContents: Obsolete entry $words[1] in $contentsfile ! Entry not used.\n"; Chris@381: } Chris@381: } else { Chris@381: # look for the AutoAdd section, should be the second word Chris@381: if ((@words >= 2) && ($words[1] eq $autoadd)) { $autoaddsection = 1; } Chris@381: # push the red line in an array Chris@381: push(@lines, $_); Chris@381: } Chris@381: } Chris@381: close(CFILE); Chris@381: } else { Chris@381: $newline = "% MATLAB Files in directory $LocalActDir\n%\n"; Chris@381: push(@lines, $newline); Chris@381: Chris@381: } Chris@381: Chris@381: # collect the file names, that were not included in original C|contents.m Chris@381: foreach $name (@localnames) { Chris@381: if (! defined $nameincontents{$name}) { Chris@381: if (! ($mfilename{$name} =~ /contents/i)) { Chris@381: $newline = sprintf("%% %-13s - %s\n", $mfilename{$name}, $apropos{$name}); Chris@381: push(@autoaddlines, $newline); Chris@381: } Chris@381: } Chris@381: } Chris@381: Chris@381: # write/update C|contents.m only if variable is set Chris@381: if ($var{'writecontentsm'} eq 'yes') { Chris@381: unlink($contentsfile); Chris@381: open(CFILE,">$contentsfile") || die("Cannot open contents file $contentsfile: $!\n"); Chris@381: # write old C|contents.m or header of new file, as long as comment lines Chris@381: foreach $line (@lines) { Chris@381: if ($emptylineflag == 0) { Chris@381: if ($line =~ /^\s*%/) { print CFILE $line; } Chris@381: else { $emptylineflag = 1; push(@emptylines, $line); } Chris@381: } else { push(@emptylines, $line); } Chris@381: } Chris@381: # add header of AutoAdd section Chris@381: if (($autoaddsection == 0) && (@autoaddlines > 0)) { print CFILE "%\n% $autoadd\n"; } Chris@381: # add autoadd section lines (previously undocumented files Chris@381: foreach $line (@autoaddlines) { print CFILE $line; } Chris@381: # add tail of original C|contents.m (everything behind first non-comment line) Chris@381: foreach $line (@emptylines) { print CFILE $line; } Chris@381: print CFILE "\n"; Chris@381: close CFILE; Chris@381: if ($opt_silent) { print "\r"; } Chris@381: print " Contents file created/updated: $contentsfile\t"; Chris@381: if (!$opt_silent) { print "\n"; } Chris@381: } Chris@381: } Chris@381: Chris@381: Chris@381: #======================================================================== Chris@381: # Replace found special characters with their HTMl Entities Chris@381: #======================================================================== Chris@381: sub SubstituteHTMLEntities { Chris@381: local($_) = @_; Chris@381: Chris@381: # Replace & <-> & < <-> < > <-> > " <-> " Chris@381: s/&/&/g; s/\/>/g; s/\"/"/g; Chris@381: return $_; Chris@381: } Chris@381: Chris@381: #======================================================================== Chris@381: # Replace found m-filenamestring with full link. Chris@381: #======================================================================== Chris@381: sub SubstituteName2Link { Chris@381: local($_, $funname) = @_; Chris@381: local($refstr1, $refstr2, $reffound); Chris@381: Chris@381: # Look for something matching in the line Chris@381: if ( /(\W+)($funname)(\W+)/i ) { Chris@381: $reffound = $2; chris@388: $refstr1 = ""; Chris@381: $refstr2 = "<\/a>"; Chris@381: # Do links only for exact case match Chris@381: if ( ($var{'links2filescase'} eq 'exact') || ($var{'links2filescase'} eq 'exactvery') ) { Chris@381: if ( /(\W+)($funname)(\W+)/g ) { Chris@381: s/(\W+)($funname)(\W+)/$1$refstr1$funname$refstr2$3/g; Chris@381: } Chris@381: else { Chris@381: # Print info for not matching case in references, good for check up of files Chris@381: if ( ($var{'links2filescase'} eq 'exactvery') ) { Chris@381: print "Diff in case found: $funname (case of file name) <-> $reffound (case in source code)\n"; Chris@381: print " (source line) $_ \n"; Chris@381: } Chris@381: } Chris@381: } Chris@381: # Do links for exact match and additionally for all upper case (often used in original matlab help text) Chris@381: elsif ( ($var{'links2filescase'} eq 'exactupper') ) { Chris@381: s/(\W+)($funname)(\W+)/$1$refstr1$2$refstr2$3/g; Chris@381: $funname2 = "\U$funname\E"; Chris@381: s/(\W+)($funname2)(\W+)/$1$refstr1$2$refstr2$3/g; Chris@381: } Chris@381: # Do links for all case mixes, this calls for trouble under LINUX/UNIX Chris@381: else { #elsif ( ($var{'links2filescase'} eq 'all') ) Chris@381: s/(\W+)($funname)(\W+)/$1$refstr1$2$refstr2$3/ig; Chris@381: } Chris@381: } Chris@381: Chris@381: return $_; Chris@381: } Chris@381: Chris@381: #======================================================================== Chris@381: # Construct the html files for each matlab file. Chris@381: # Need to reread each matlab file to find the help text. Chris@381: # Note that we can't do this in a single loop because sometimes Chris@381: # the help text maybe before the function declaration. Chris@381: #======================================================================== Chris@381: sub ConstructHTMLFiles Chris@381: { Chris@381: local(*MFILE); Chris@381: local(*HFILE); Chris@381: Chris@381: local($filescreated) = 0; Chris@381: local($functionline); Chris@381: Chris@381: foreach $name (@names) { Chris@381: # Create cross reference information already here, used for keywords as well Chris@381: # Construct list of referenced functions Chris@381: @xref = @{'depcalls'.$name}; # the functions, that this m-file calls Chris@381: @yref = @{'depcalled'.$name}; # the functions, that this m-file is called from Chris@381: # print " depcalls: @{'depcalls'.$name}\n depcalled: @{'depcalled'.$name}\n"; Chris@381: # foreach $cname (@names) { next if $cname eq $name; push(@yref,$cname) if grep(/$name/,@{'depcalls'.$cname}); } Chris@381: Chris@381: Chris@381: # Open m-file and html-file Chris@381: open(MFILE,"<$mfile{$name}"); Chris@381: open(HFILE,">$hfile{$name}"); Chris@381: Chris@381: # Write the header of HTML file Chris@381: print HFILE "$TextDocTypeHTML\n\n\n$var{'codeheadmeta'}\n$TextMetaCharset\n$var{'csslink'}\n"; Chris@381: Chris@381: # Write meta tags: use apropos (one line function description) for description Chris@381: # and cross reference function names for keywords (any better ideas?) Chris@381: print HFILE "\n"; Chris@381: print HFILE "\n"; Chris@381: Chris@381: # Write Title and start body of html-file Chris@381: print HFILE "$var{'texttitlefiles'} $mfilename{$name}\n\n"; Chris@381: print HFILE "\n"; chris@410: print HFILE "
\n"; Chris@381: print HFILE "

$var{'textheaderfiles'} $mfilename{$name}

\n"; chris@401: chris@401: # http://test.soundsoftware.ac.uk/cannam/projects/smallbox/repository/annotate/DL/RLS-DLA/SolveFISTA.m chris@410: # print HFILE "
View in repository\n"; chris@401: Chris@381: print HFILE "$var{'codehr'}\n"; Chris@381: Chris@381: # include links to short/long - local/global index and C|contents.m Chris@381: &ConstructLinks2Index(HFILE, $hfileindexpath{$name}, $mfiledir{$name}, 'local'); Chris@381: Chris@381: # If this is a function, then write out the first line as a synopsis Chris@381: if ($mtype{$name} eq "function") { Chris@381: print HFILE "

Function Synopsis

\n"; Chris@381: print HFILE "
$synopsis{$name}
\n$var{'codehr'}\n"; Chris@381: } Chris@381: Chris@381: # Look for the matlab help text block Chris@381: $functionline = "\n"; Chris@381: do { Chris@381: $_ = ; Chris@381: # remember functionline, if before help text block Chris@381: if (/^\s*function/) { $functionline = $_; } Chris@381: } until (/^\s*%/ || eof); Chris@381: if (! (eof(MFILE))) { Chris@381: print HFILE "

Help text

\n"; Chris@381: print HFILE "
\n";
Chris@381:          while (/^\s*%/) {
Chris@381:             # First remove leading % and white space, then Substitute special characlers
Chris@381:             s/^\s*%//;
Chris@381:             $_ = &SubstituteHTMLEntities($_);
Chris@381: 
Chris@381:             # check/create cross references
Chris@381:             foreach $funname (@{'all'.$name}) {
Chris@381:                if ($funname =~ /simulink/) { print "\n Simulink - Filename: $name;  scanname: $funname\n"; }
Chris@381:                next if $funname eq $name;
Chris@381:                $_ = &SubstituteName2Link($_, $funname);
Chris@381:             }
Chris@381:             print HFILE $_;
Chris@381:             if (! eof) { $_ = ; }
Chris@381:          }
Chris@381:          print HFILE "
\n$var{'codehr'}\n"; Chris@381: } Chris@381: Chris@381: # Write the cross reference information Chris@381: if (@xref || @yref) { Chris@381: print HFILE "

Cross-Reference Information

\n"; Chris@381: print HFILE "\n\n\n\n\n\n\n
"; Chris@381: if (@xref) { Chris@381: print HFILE "This $mtype{$name} calls"; Chris@381: } Chris@381: print HFILE ""; Chris@381: if (@yref) { Chris@381: print HFILE "This $mtype{$name} is called by"; Chris@381: } Chris@381: print HFILE "
"; Chris@381: if (@xref) { Chris@381: print HFILE "\n
    \n"; Chris@381: foreach $cname (sort @xref) { Chris@381: print HFILE "
  • $mfilename{$cname}
  • \n"; Chris@381: } Chris@381: print HFILE "
\n"; Chris@381: } Chris@381: print HFILE "
"; Chris@381: if (@yref) { Chris@381: print HFILE "\n
    \n"; Chris@381: foreach $cname (sort @yref) { Chris@381: print HFILE "
  • $mfilename{$cname}
  • \n"; Chris@381: } Chris@381: print HFILE "
\n"; Chris@381: } Chris@381: print HFILE "
\n"; Chris@381: print HFILE "$var{'codehr'}\n"; Chris@381: } Chris@381: Chris@381: # Include source text if requested Chris@381: if (($var{'includesource'} eq 'yes') && (! ($mfilename{$name} =~ /^contents$/i))) { Chris@381: print HFILE "

Listing of $mtype{$name} $mfilename{$name}

\n"; Chris@381: seek(MFILE,0,0); Chris@381: print HFILE "
\n";
Chris@381:          $IsStillHelp = 2;
Chris@381:          print HFILE $functionline;    # functionline from scanning of help
Chris@381:          while () {
Chris@381:             if ($IsStillHelp == 2) {
Chris@381:                next     if (/^\s*$/);
Chris@381:                next     if (/^\s*function/);
Chris@381:                if (/^\s*%/) { $IsStillHelp = 1; next; }
Chris@381:             } elsif ($IsStillHelp == 1) {
Chris@381:                next     if (/^\s*%/);
Chris@381:                $IsStillHelp = 0;
Chris@381:             }
Chris@381:             
Chris@381:             # Substritute special characters
Chris@381:             $_ = &SubstituteHTMLEntities($_);
Chris@381:             
Chris@381:             # check for comment in line and format with css em
chris@400:             s/^(.*)%(.*?)([\s\r\n]+)$/$1%$2<\/em>$3/;
Chris@381: 
Chris@381:             # check/create cross references
Chris@381:             foreach $funname (@{'all'.$name}) {
Chris@381:                next if $funname eq $name;
Chris@381:                $_ = &SubstituteName2Link($_, $funname);
Chris@381:             }
Chris@381:             print HFILE $_;
Chris@381:          }
Chris@381:          print HFILE "
\n$var{'codehr'}\n"; Chris@381: } Chris@381: Chris@381: # Include info about author from authorfile Chris@381: &WriteFile2Handle($var{'authorfile'}, HFILE) ; Chris@381: Chris@381: print HFILE "\n"; Chris@381: print HFILE "\n"; chris@410: print HFILE "
\n\n\n"; Chris@381: close(MFILE); Chris@381: close(HFILE); Chris@381: Chris@381: # Print name of finished file Chris@381: if ($opt_silent) { print "\r"; } Chris@381: print " HTML-File created: $hfile{$name}\t"; Chris@381: if (!$opt_silent) { print "\n"; } Chris@381: $filescreated++; Chris@381: } Chris@381: Chris@381: print "\n$PROGRAM: $indexcreated index and $filescreated files created.\n"; Chris@381: } Chris@381: Chris@381: #======================================================================== Chris@381: # Function: CheckFileName Chris@381: # Purpose: . Chris@381: #======================================================================== Chris@381: sub CheckFileName { Chris@381: local($filename, $description) = @_; Chris@381: local(*CHECKFILE); Chris@381: Chris@381: open(CHECKFILE,"<$filename") || do { Chris@381: if ($description eq '') {$description = 'file';} Chris@381: # if (!$opt_silent) { print "Cannot open $description $filename: $!\n"; } Chris@381: print "Cannot open $description $filename: $!\n"; Chris@381: return 1; Chris@381: }; Chris@381: close(CHECKFILE); Chris@381: return 0; Chris@381: Chris@381: } Chris@381: Chris@381: #======================================================================== Chris@381: # Function: CheckDirName Chris@381: # Purpose: . Chris@381: #======================================================================== Chris@381: sub CheckDirName { Chris@381: local($dirname, $description) = @_; Chris@381: local(*CHECKDIR); Chris@381: Chris@381: opendir(CHECKDIR,"$dirname") || die ("Cannot open $description directory $dirname: $!\n"); Chris@381: closedir(CHECKDIR); Chris@381: } Chris@381: Chris@381: #======================================================================== Chris@381: # Function: WriteFile2Handle Chris@381: # Purpose: . Chris@381: #======================================================================== Chris@381: sub WriteFile2Handle { Chris@381: local($filename, *WRITEFILE) = @_; Chris@381: local(*READFILE); Chris@381: Chris@381: if ($filename ne '') { Chris@381: open(READFILE,"<$filename"); Chris@381: @filecontents = ; Chris@381: close(READFILE); Chris@381: print WRITEFILE "@filecontents\n"; Chris@381: # if (!$opt_silent) {print " Contents of $filename added\n"}; Chris@381: } Chris@381: } Chris@381: Chris@381: Chris@381: #======================================================================== Chris@381: # Function: GetConfigFile Chris@381: # Purpose: Read user's configuration file, if such exists. Chris@381: #======================================================================== Chris@381: sub GetConfigFile Chris@381: { Chris@381: local($filename) = @_; Chris@381: local(*CONFIG); Chris@381: local($value); Chris@381: Chris@381: if (&CheckFileName($filename, 'configuration file')) { Chris@381: # if (!$opt_silent) { print " Proceeding using built-in defaults for configuration.\n"; } Chris@381: print " Proceeding using built-in defaults for configuration.\n"; Chris@381: return 0; Chris@381: }; Chris@381: Chris@381: open(CONFIG,"< $filename"); Chris@381: while () { Chris@381: s/#.*$//; Chris@381: next if /^\s*$/o; Chris@381: Chris@381: # match keyword: process one or more arguments Chris@381: # keyword set Chris@381: if (/^\s*set\s+(\S+)\s*=\s*(.*)/) { Chris@381: # setting a configuration variable Chris@381: if (defined $var{$1}) { Chris@381: $var{$1} = $2; Chris@381: if ($debug > 3) { print "$1: $var{$1}\n"; } Chris@381: } Chris@381: else { Chris@381: print "$PROGRAM: unknown variable `$1' in configuration file\n" Chris@381: } Chris@381: } else { Chris@381: chop($_); Chris@381: print "$PROGRAM: unknown keyword in configuration file in line: `$_'\n" Chris@381: } Chris@381: } Chris@381: close CONFIG; Chris@381: 1; Chris@381: } Chris@381: Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # DisplayHelp - display help text using -h or -help command-line switch Chris@381: #------------------------------------------------------------------------ Chris@381: sub DisplayHelp Chris@381: { Chris@381: $help=< generation of docu, else display of help) Chris@381: Chris@381: $PROGRAM -dirmfiles matlab -dirhtml html Chris@381: (generate html documentation for all m-files in directory matlab, Chris@381: place html files in directory html, use built-in defaults for Chris@381: all other parameters, this way all m-files in the directory Chris@381: matlab and below are converted and the generated html-files are Chris@381: placed in the directory html and below producing the same Chris@381: directory structure than below matlab) Chris@381: Chris@381: $PROGRAM -quiet Chris@381: (use built-in parameters from perl script, if configuration Chris@381: file is found use these settings as well, do generation, Chris@381: no display except critical errors, status of conversion and result) Chris@381: Chris@381: $PROGRAM -m toolbox -dirhtml doc/html -r yes -p no Chris@381: (convert all m-files in directory toolbox and below and place Chris@381: the generated html files in directory doc/html, read all m-files Chris@381: recursively, however, the generated html files are placed in one Chris@381: directory) Chris@381: Chris@381: $PROGRAM -m toolbox -dirhtml doc/html -i no -r no Chris@381: (convert all m-files in directory toolbox and place Chris@381: the generated html files in directory doc/html, do not read m-files Chris@381: recursively, do not include source code in documentation) Chris@381: Chris@381: EofHelp Chris@381: Chris@381: die "$help"; Chris@381: } Chris@381: Chris@381: #------------------------------------------------------------------------ Chris@381: # DisplayTodo - display ToDo list using -t or -todo command-line switch Chris@381: #------------------------------------------------------------------------ Chris@381: sub DisplayTodo Chris@381: { Chris@381: $todo=< 0) { Chris@381: print "List of all variables and their values\n"; Chris@381: foreach (sort keys %var) Chris@381: { Chris@381: if ($var{$_} eq '') { Chris@381: $value = "empty"; Chris@381: } else { Chris@381: $value = $var{$_}; Chris@381: } Chris@381: print " $_\n $value\n"; Chris@381: } Chris@381: print "\n\n"; Chris@381: } Chris@381: } Chris@381: Chris@381: Chris@381: __END__ Chris@381: :endofperl