comparison extra/soundsoftware/matlab-docs.pl @ 416:165e443660c4 live

Merge
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Tue, 10 May 2011 10:09:14 +0100
parents e7ba81c8dc5a
children
comparison
equal deleted inserted replaced
399:e7c58b88e670 416:165e443660c4
1 @rem = '--*-Perl-*--';
2 @rem = '
3 @echo off
4 perl -w -S %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
5 goto endofperl
6 @rem ';
7 # perl -w -S %0.bat "$@"
8 #!/usr/bin/perl
9 #
10 # mtree2html_2000 - produce html files from Matlab m-files.
11 # use configuration file for flexibility
12 # can process tree of directories
13 #
14 # Copyright (C) 1996-2000 Hartmut Pohlheim. All rights reserved.
15 # includes small parts of m2html from Jeffrey C. Kantor 1995
16 #
17 # Author: Hartmut Pohlheim
18 # History: 06.03.1996 file created
19 # 07.03.1996 first working version
20 # 08.03.1996 modularized, help text only once included
21 # 11.03.1996 clean up, some functions rwritten
22 # 18.04.1996 silent output with writing in one line only
23 # version 0.20 fixed
24 # 14.05.1996 start of adding tree structure, could create tree
25 # 15.05.1996 creating of index files for every directory
26 # 17.05.1996 first working version except compact A-Z index
27 # 20.05.1996 cleanup of actual version, more variables and
28 # configurable settings
29 # 21.05.1996 reading, update and creation of contents.m added
30 # 22.05.1996 creation of short index started
31 # 28.05.1996 jump letters for short index,
32 # 3 different directory indexes (short/long/contents)
33 # 29.05.1996 major cleanup, short and long index created from one function
34 # links for HTML and Indexes from 1 function,
35 # version 0.9
36 # 30.05.1996 contents.m changed to Contents.m (because unix likes it)
37 # function definition can be in first line of m file before comments
38 # version 0.91 fixed
39 # 03.06.1996 contents file can be written as wanted, the links will be correct
40 # cross references in help block of m-file will be found and
41 # converted, even if the name of the function is written upper case
42 # version 0.92 fixed
43 # 05.06.1996 construction of dependency matrix changed, is able now to process
44 # even the whole matlab tree (previous version needed to much memory)
45 # removed warning for contents files in different directories
46 # version 0.94 fixed
47 # 06.06.1996 new link name matrices for ConstructHTMLFile created,
48 # everything is done in ConstructDependencyMatrix,
49 # both dependencies (calls and called) and matrix
50 # with all mentioned names in this m-file, thus, much
51 # less scanning in html construction
52 # script is now (nearly) linear scalable, thus, matlab-toolbox
53 # tree takes less than 1 hour on a Pentium120, with source
54 # version 0.96 fixed
55 # 10.06.1996 order of creation changed, first all indexes (includes
56 # update/creation of contents.m) and then ConstructDepency
57 # thus, AutoAdd section will be linked as well
58 # excludenames extended, some more common word function names added
59 # version 0.97 fixed
60 # 17.02.1998 writecontentsm as command line parameter added
61 # error of file not found will even appear when silent
62 # version 1.02
63 # 21.05.2000 mark comments in source code specially (no fully correct,
64 # can't handle % in strings)
65 # version 1.11
66 # 05.11.2000 link also to upper and mixed case m-files
67 # searching for .m files now really works (doesn't find grep.com any longer)
68 # file renamed to mtree2html2001
69 # generated html code now all lower case
70 # inclusion of meta-description and meta-keywords in html files
71 # HTML4 compliance done (should be strict HTML4.0, quite near XHTML)
72 # version 1.23
73 #
74 # 29.03.2011 (Chris Cannam) add frames option.
75
76 $VERSION = '1.23';
77 ($PROGRAM = $0) =~ s@.*/@@; $PROGRAM = "\U$PROGRAM\E";
78 $debug = 1;
79
80 #------------------------------------------------------------------------
81 # Define platform specific things
82 #------------------------------------------------------------------------
83 # suffix for files to search is defined twice
84 # the first ($suffix) is for string creation and contains the . as well
85 # the second ($suffixforsearch) is for regular expression, handling of . is quite special
86 $suffix = ".m";
87 $suffixforsearch = "m";
88 # the directory separator
89 $dirsep = "/";
90 # what is the current directory
91 $diract = ".";
92
93 #------------------------------------------------------------------------
94 # Define all variables and their standard settings
95 # documentation of variables is contained in accompanying rc file
96 #------------------------------------------------------------------------
97 %var =
98 (
99 'authorfile', '',
100 'codebodyfiles', '',
101 'codebodyindex', '',
102 'codeheadmeta', '<meta name="author of conversion perl script" content="Hartmut Pohlheim" />',
103 'codehr', '<hr size="3" noshade="noshade" />',
104 'codeheader', '',
105 'configfile', 'matlab-docs.conf',
106 'csslink', '',
107 'dirmfiles', $diract,
108 'dirhtml', $diract,
109 'exthtml', '.html',
110 'frames', 'yes',
111 'filenametopframe', 'index',
112 'filenameindexlongglobal', 'indexlg',
113 'filenameindexlonglocal', 'indexll',
114 'filenameindexshortglobal', 'indexsg',
115 'filenameindexshortlocal', 'indexsl',
116 'filenameextensionframe', 'f',
117 'filenameextensionindex', 'i',
118 'filenameextensionjump', 'j',
119 'filenamedirshort', 'dirtops',
120 'filenamedirlong', 'dirtopl',
121 'filenamedircontents', 'dirtopc',
122 'includesource', 'yes',
123 'links2filescase', 'all',
124 'processtree', 'yes',
125 'producetree', 'yes',
126 'textjumpindexlocal', 'Local Index',
127 'textjumpindexglobal', 'Global Index',
128 'texttitleframelayout', 'Documentation of Matlab Files',
129 'texttitleindexalldirs', 'Index of Directories',
130 'textheaderindexalldirs', 'Index of Directories',
131 'texttitleindex', '',
132 'textheaderindex', '',
133 'texttitlefiles', 'Documentation of ',
134 'textheaderfiles', 'Documentation of ',
135 'usecontentsm', 'yes',
136 'writecontentsm', 'no'
137 );
138
139
140 # define all m-file names, that should be excluded from linking
141 # however, files will still be converted
142 @excludenames = ( 'all','ans','any','are',
143 'cs',
144 'demo','dos',
145 'echo','edit','else','elseif','end','exist',
146 'flag','for','function',
147 'global',
148 'help',
149 'i','if','inf','info',
150 'j',
151 'more',
152 'null',
153 'return',
154 'script','strings',
155 'what','which','while','who','whos','why',
156 );
157
158 # Text for inclusion in created HTML/Frame files: Doctype and Charset
159 $TextDocTypeHTML = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">';
160 $TextDocTypeFrame = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" "http://www.w3.org/TR/REC-html40/frameset.dtd">';
161 $TextMetaCharset = '<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />';
162
163 #------------------------------------------------------------------------
164 # Read the command line arguments
165 #------------------------------------------------------------------------
166 if (@ARGV == 0) {
167 &DisplayHelp() if &CheckFileName($var{'configfile'}, 'configuration file');
168 }
169
170 # Print provided command line arguments on screen
171 foreach (@ARGV) { print " $_\n "; }
172
173 # Get the options
174 use Getopt::Long;
175 @options = ('help|h', 'todo|t', 'version|v',
176 'authorfile|a=s', 'configfile|c=s', 'dirhtml|html|d=s',
177 'dirmfiles|mfiles|m=s', 'includesource|i=s',
178 'processtree|r=s', 'producetree|p=s',
179 'silent|quiet|q', 'writecontentsm|w=s');
180 &GetOptions(@options) || die "use -h switch to display help statement\n";
181
182
183 # Display help or todo list, when requested
184 &DisplayHelp() if $opt_help;
185 &DisplayTodo() if $opt_todo;
186 die "$PROGRAM v$VERSION\n" if $opt_version;
187
188 $exit_status = 0;
189
190 #------------------------------------------------------------------------
191 # Read the config file
192 #------------------------------------------------------------------------
193 $var{'configfile'} = $opt_configfile if $opt_configfile;
194 &GetConfigFile($var{'configfile'});
195
196
197 #------------------------------------------------------------------------
198 # Process/Check the command line otions
199 #------------------------------------------------------------------------
200 $var{'dirhtml'} = $opt_dirhtml if $opt_dirhtml;
201 if (!(substr($var{'dirhtml'}, -1, 1) eq $dirsep)) { $var{'dirhtml'} = $var{'dirhtml'}.$dirsep; }
202 $var{'dirmfiles'} = $opt_dirmfiles if $opt_dirmfiles;
203 if (!(substr($var{'dirmfiles'}, -1, 1) eq $dirsep)) { $var{'dirmfiles'} = $var{'dirmfiles'}.$dirsep; }
204
205 $var{'authorfile'} = $opt_author if $opt_author;
206 $var{'includesource'} = $opt_includesource if $opt_includesource;
207 if ($var{'includesource'} ne 'no') { $var{'includesource'} = 'yes'; }
208 $var{'processtree'} = $opt_processtree if $opt_processtree;
209 if ($var{'processtree'} ne 'no') { $var{'processtree'} = 'yes'; }
210 $var{'producetree'} = $opt_producetree if $opt_producetree;
211 if ($var{'producetree'} ne 'no') { $var{'producetree'} = 'yes'; }
212 if ($var{'processtree'} eq 'no') { $var{'producetree'} = 'no'; }
213 if ($var{'frames'} ne 'no') { $var{'frames'} = 'yes'; }
214 # if (($var{'processtree'} eq 'yes') && ($var{'producetree'} eq 'no')) { $var{'usecontentsm'} = 'no'; }
215
216 $var{'writecontentsm'} = $opt_writecontentsm if $opt_writecontentsm;
217
218 #------------------------------------------------------------------------
219 # Do the real stuff
220 #------------------------------------------------------------------------
221
222 # Print variables on screen, when not silent
223 &ListVariables if !$opt_silent;
224
225 # Check the author file
226 if ($var{'authorfile'} ne '') {
227 if (!($var{'authorfile'} =~ m,^/,)) {
228 # relative path: treat as relative to config file
229 my $cfd = $var{'configfile'};
230 $cfd =~ s,/[^/]*$,/,;
231 $cfd =~ s,^[^/]*$,.,;
232 $var{'authorfile'} = "$cfd/" . $var{'authorfile'};
233 }
234 if (&CheckFileName($var{'authorfile'}, 'author file')) {
235 $var{'authorfile'} = '';
236 if (!$opt_silent) { print " Proceeding without author information!\n"; }
237 }
238 }
239
240 # Call the function doing all the real work
241 &ConstructNameMatrix;
242
243 &ConstructDependencyMatrix;
244
245 &ConstructAllIndexFiles;
246
247 &ConstructHTMLFiles;
248
249 exit $exit_status;
250
251 #------------------------------------------------------------------------
252 # Construct list of all mfile names and initialize various data arrays.
253 #------------------------------------------------------------------------
254 sub ConstructNameMatrix
255 {
256 local(*MFILE);
257 local($file, $dirname);
258 local(@newdirectories);
259 local(%localnames);
260
261 $RecDeep = 0;
262 &ParseTreeReadFiles($var{'dirmfiles'}, $RecDeep);
263
264 foreach $dirname (@directories) {
265 if ($dirnumbermfiles{$dirname} > 0) {
266 push(@newdirectories, $dirname);
267 if (! defined($contentsname{$dirname})) {
268 $contentsname{$dirname} = 'Contents';
269 if (($var{'writecontentsm'} eq 'no') && ($var{'usecontentsm'} eq 'yes')) {
270 print "\r ParseTree - for directory $dirname no contents file found!\n";
271 print " create one or enable writing of contents file (writecontentsm = yes)!\n";
272 }
273 }
274 }
275 }
276 @alldirectories = @directories;
277 @directories = @newdirectories;
278
279 foreach $dirname (@directories) {
280 if ($debug > 0) { print "Dir: $dirname \t\t $dirnumbermfiles{$dirname} \t$contentsname{$dirname}\n"; }
281 }
282
283 @names = sort(keys %mfile);
284
285 # check, if name of directory is identical to name of file
286 @dirsinglenames = values(%dirnamesingle);
287 grep($localnames{$_}++, @dirsinglenames);
288 @dirandfilename = grep($localnames{$_}, @names);
289 if (@dirandfilename) {
290 print "\r Name clash between directory and file name: @dirandfilename\n";
291 print " These files will be excluded from linking!\n";
292 push(@excludenames, @dirandfilename);
293 }
294
295 # construct names matrix for help text linking
296 # exclude some common words (and at the same time m-functions) from linking in help text
297 grep($localnames{$_}++, @excludenames);
298 @linknames = grep(!$localnames{$_}, @names);
299
300 if ($debug > 2) { print "linknames (names of found m-files):\n @linknames\n"; }
301
302 }
303
304 #------------------------------------------------------------------------
305 # Parse tree and collect all Files
306 #------------------------------------------------------------------------
307 sub ParseTreeReadFiles
308 {
309 local($dirname, $localRecDeep) = @_;
310 local($file, $name, $filewosuffix);
311 local($dirhtmlname, $dirmode);
312 local($relpath, $relpathtoindex, $replacevardir);
313 local(*CHECKDIR, *AKTDIR);
314 local(@ALLEFILES);
315
316 opendir(AKTDIR, $dirname) || die "ParseTree - Can't open directory $dirname: $!";
317 if ($debug > 1) { print "\nDirectory: $dirname\n"; }
318
319 # create relative path
320 $_ = $dirname; $replacevardir = $var{'dirmfiles'};
321 s/$replacevardir//; $relpath = $_;
322 s/[^\/]+/../g; $relpathtoindex = $_;
323
324 # producetree no
325 if ($var{'producetree'} eq 'no') { $relpath = ''; $relpathtoindex = ''; }
326
327 # names of directories (top-level and below top-level m-file-directory)
328 push(@directories, $dirname);
329 $dirnumbermfiles{$dirname} = 0; # set number of m-files for this dir to zero
330 # relative path from top-level directory, depends on directory name
331 $dirnamerelpath{$dirname} = $relpath;
332 # relative path from actual directory to top-level directory, depends on directory name
333 $dirnamerelpathtoindex{$dirname} = $relpathtoindex;
334 # recursion level for directory, depends on directory name
335 $dirnamerecdeep{$dirname} = $localRecDeep;
336
337 # only the name of the directory, without path
338 $rindexprint = rindex($dirname, $dirsep, length($dirname)-2);
339 $rindsub = substr($dirname, $rindexprint+1, length($dirname)-$rindexprint-2);
340 $dirnamesingle{$dirname} = $rindsub;
341
342 # create name of html-directories
343 $_ = $dirname;
344 s/$var{'dirmfiles'}/$var{'dirhtml'}/;
345 $dirhtmlname = $_;
346 if ($var{'producetree'} eq 'no') { $dirhtmlname = $var{'dirhtml'}; }
347 # try to open html directory, if error, then create directory,
348 # use same mode as for corresponding m-file directory
349 opendir(CHECKDIR,"$dirhtmlname") || do {
350 $dirmode = (stat($dirname))[2]; # print "$dirmode\n";
351 mkdir("$dirhtmlname", $dirmode) || die ("Cannot create directory $dirhtmlname: $! !");
352 };
353 closedir(CHECKDIR);
354
355
356 # read everything from this directory and process them
357 @ALLEFILES = readdir(AKTDIR);
358
359 foreach $file (@ALLEFILES) {
360 # exclude . and .. directories
361 next if $file eq '.'; next if $file eq '..';
362
363 # test for existense of entry (redundant, used for debugging)
364 if (-e $dirname.$file) {
365 # if it's a directory, call this function recursively
366 if (-d $dirname.$file) {
367 if ($var{'processtree'} eq 'yes') {
368 &ParseTreeReadFiles($dirname.$file.$dirsep, $localRecDeep+1);
369 }
370 }
371 # if it's a file - test for m-file, save name and create some arrays
372 elsif (-f $dirname.$file) {
373 if ($file =~ /\.$suffixforsearch$/i) {
374 # Remove the file suffix to establish the matlab identifiers
375 $filewosuffix = $file;
376 $filewosuffix =~ s/\.$suffixforsearch$//i;
377 # $filename = $name;
378
379 # Contents file in unix must start with a capital letter (Contents.m)
380 # ensure, that m-file name is lower case, except the contents file
381 if (! ($filewosuffix =~ /^contents$/i)) {
382 # if ($var{'links2filescase'} eq 'low') { $filewosuffix = "\L$filewosuffix\E"; }
383 $filewosuffixlow = "\L$filewosuffix\E";
384 }
385 else { $contentsname{$dirname} = $filewosuffix; }
386
387 # internal handle name is always lower case
388 $name = $filewosuffixlow;
389 # file name is not lower case
390 $filename = $filewosuffix;
391
392 # if don't use C|contents.m, then forget all C|contents.m
393 if ($var{'usecontentsm'} eq 'no') { if ($name =~ /contents/i) { next; } }
394
395 # if m-file with this name already exists, use directory and name for name
396 # only the first occurence of name will be used for links
397 if (defined $mfile{$name}) {
398 if (! ($name =~ /^contents$/i) ) {
399 print "\r ParseTree - Name conflict: $name in $dirname already exists: $mfile{$name} !\n";
400 print " $mfile{$name} will be used for links!\n";
401 }
402 $name = $dirname.$name;
403 }
404 # mfile name with path
405 $mfile{$name} = $dirname.$file;
406 # mfile name (without path)
407 $mfilename{$name} = $filename;
408 # mfile directory
409 $mfiledir{$name} = $dirname;
410
411 # html file name and full path, special extension of Contents files
412 if ($name =~ /contents/i) { $extrahtmlfilename = $dirnamesingle{$dirname}; }
413 else { $extrahtmlfilename = ''; }
414 $hfile{$name} = $dirhtmlname.$mfilename{$name}.$extrahtmlfilename.$var{'exthtml'};
415
416 # save relative html path
417 # if ($var{'producetree'} eq 'yes') {
418 $hfilerelpath{$name} = $relpath;
419 # } else { # if no tree to produce, relative path is empty
420 # $hfilerelpath{$name} = '';
421 # }
422
423 # create relative path from html file to directory with global index file
424 $hfileindexpath{$name} = $relpathtoindex;
425
426 # Function declaration, if one exists, set default to script
427 $synopsis{$name} = "";
428 $mtype{$name} = "script";
429
430 # First comment line
431 $apropos{$name} = "";
432
433 # count number of m-files in directories
434 $dirnumbermfiles{$dirname}++;
435
436 if ($debug > 1) {
437 if ($opt_silent) { print "\r"; }
438 print " ParseTree: $name \t\t $mfile{$name} \t\t $hfile{$name}\t\t";
439 if (!$opt_silent) { print "\n"; }
440 }
441 }
442 }
443 else {
444 print "Unknown type of file in $dirname: $file\n";
445 }
446 }
447 else { print "Error: Not existing file in $dirname: $file\n"; }
448 }
449
450 closedir(AKTDIR)
451
452 }
453
454 #------------------------------------------------------------------------
455 # Construct Dependency matrix
456 # $dep{$x,$y} > 0 if $x includes a reference to $y.
457 #------------------------------------------------------------------------
458 sub ConstructDependencyMatrix
459 {
460 &ConstructDependencyMatrixReadFiles('all');
461 &ConstructDependencyMatrixReally;
462 }
463
464
465 #------------------------------------------------------------------------
466 # Construct Dependency matrix
467 # $dep{$x,$y} > 0 if $x includes a reference to $y.
468 #------------------------------------------------------------------------
469 sub ConstructDependencyMatrixReadFiles
470 {
471 local($whatstring) = @_;
472 local(*MFILE);
473 local($name, $inames);
474 local(%symbolsdep, %symbolsall);
475
476 # Initialize as all zeros.
477 # foreach $name (@names) { grep($dep{$name,$_}=0,@names); if ($debug > 0) { print "\r DepMatrix anlegen: $name\t$#names\t"; } }
478
479 # Compute the dependency matrix
480 $inames = -1;
481 foreach $name (@names) {
482 # Read each file and tabulate the distinct alphanumeric identifiers in
483 # an array of symbols. Also scan for:
484 # synopsis: The function declaration line
485 # apropos: The first line of the help text
486
487 # look for whatstring, if all: process every file, if contents: process only contents files
488 if ($whatstring eq 'contents') { if (! ($name =~ /contents$/i) ) { next; } }
489 elsif ($whatstring eq 'all') { } # do nothing
490 else { print "\r ConstructDependency: Unknown parameter whatstring: $whatstring \n"; }
491
492 undef %symbolsall; undef %symbolsdep;
493 open(MFILE,"<$mfile{$name}") || die("Can't open $mfile{$name}: $!\n");
494 while (<MFILE>) {
495 chop;
496
497 # Split on nonalphanumerics, then look for all words, used for links later
498 # this one for all references
499 @wordsall = grep(/[a-zA-Z]\w*/, split('\W',$_));
500 # set all words to lower case for link checking
501 undef @wordsall2;
502 # do case conversion not, case checking is done later
503 foreach (@wordsall) { push(@wordsall2, "\L$_\E"); }
504 # @wordsall2 = @wordsall;
505 grep($symbolsall{$_}++, @wordsall2);
506
507 # Store first comment line, skip all others.
508 if (/^\s*%/) {
509 if (!$apropos{$name}) {
510 s/^\s*%\s*//; # remove % and leading white spaces on line
511 $_ = &SubstituteHTMLEntities($_);
512 $apropos{$name} = $_;
513 }
514 next;
515 }
516
517 # If it's the function declaration line, then store it and skip
518 # but only, when first function definition (multiple function lines when private subfunctions in file
519 if ($synopsis{$name} eq '') {
520 if (/^\s*function/) {
521 s/^\s*function\s*//;
522 $synopsis{$name} = $_;
523 $mtype{$name} = "function";
524 next;
525 }
526 }
527
528 # Split off any trailing comments
529 if ($_ ne '') {
530 # this one for references in program code only
531 # when syntax parsing, here is a working place
532 ($statement) = split('%',$_,1);
533 @wordsdep = grep(/[a-zA-Z]\w*/,split('\W',$statement));
534 # do case conversion not, case checking is done later
535 undef @wordsdep2;
536 foreach (@wordsdep) { push(@wordsdep2, "\L$_\E"); }
537 grep($symbolsdep{$_}++, @wordsdep2);
538 }
539 }
540 close MFILE;
541
542 # compute intersection between %symbolsall and @linknames
543 delete($symbolsall{$name});
544 # foreach $localsumall ($symbolsall) {
545 # $localsumall = "\L$localsumall\E";
546 # }
547 @{'all'.$name} = grep($symbolsall{$_}, @linknames);
548
549 # compute intersection between %symbolsdep and @linknames
550 delete($symbolsdep{$name});
551 @{'depcalls'.$name} = grep($symbolsdep{$_}, @linknames);
552
553 $inames++; print "\r DepCallsMatrix: $inames/$#names\t $name\t";
554 if ($debug > 2) { print "\n depnames: @{'depcalls'.$name}\n all: @{'all'.$name}\n"; }
555 }
556 }
557
558
559 #------------------------------------------------------------------------
560 # Construct Dependency matrix
561 # $dep{$x,$y} > 0 if $x includes a reference to $y.
562 #------------------------------------------------------------------------
563 sub ConstructDependencyMatrixReally
564 {
565 local($inames, $name);
566
567 $inames = -1;
568 foreach $name (@names) { undef %{'depint'.$name}; }
569 foreach $name (@names) {
570 grep(${'depint'.$_}{$name}++, @{'depcalls'.$name});
571 $inames++; print "\r DepCalledMatrix1: $inames/$#names\t $name\t";
572 }
573 $inames = -1;
574 foreach $name (@names) {
575 # compute intersection between %depint.name{$_} and @linknames
576 if (defined (%{'depint'.$name})) { @{'depcalled'.$name} = grep(${'depint'.$name}{$_}, @linknames); }
577 $inames++; print "\r DepCalledMatrix2: $inames/$#names\t $name\t";
578 if ($debug > 2) { print "\n depcalled: @{'depcalled'.$name}\n"; }
579 }
580
581 }
582
583
584 #========================================================================
585 # Construct all index files
586 #========================================================================
587 sub ConstructAllIndexFiles
588 {
589 local(@localnames);
590 local($ActDir);
591 local($name);
592
593 # define variables and names for frame target
594 $GlobalNameFrameMainLeft = 'Cont_Main';
595 $GlobalNameFrameMainRight = 'Cont_Lower';
596 $GlobalNameFrameAZIndexsmall = 'IndexAZindex';
597 $GlobalNameFrameAZIndexjump = 'IndexAZjump';
598
599 $indexcreated = 0;
600
601 &ConstructHighestIndexFile;
602 $indexcreated++;
603
604 # if ($var{'producetree'} eq 'yes') {
605 # moved next 2 lines out of if for producetree no
606 # &ConstructHighestIndexFile;
607 # $indexcreated++;
608
609 foreach $ActDir (@directories) {
610 undef @localnames;
611 foreach $name (@names) {
612 local($pathsubstr) = substr($mfile{$name}, 0, rindex($mfile{$name}, "/")+1);
613 if ($ActDir eq $pathsubstr) {
614 if ($debug > 1) { print "IndexFile: $pathsubstr ActDir: $ActDir Hfilerelpath: $hfilerelpath{$name}\n"; }
615 push(@localnames, $name);
616 }
617 }
618 if ($debug > 2) { print "localnames: @localnames\n"; }
619 # create contents file and short|long index of files in local directory
620 &ConstructContentsmFile($ActDir, @localnames);
621 &ConstructAZIndexFile($ActDir, 'short', 'local', @localnames);
622 &ConstructAZIndexFile($ActDir, 'long', 'local', @localnames);
623 $indexcreated+=2;
624 }
625 # } else {
626 # &ConstructContentsmFile($var{'dirmfiles'}, @names);
627 # }
628
629 # create short|long index of files in all directory
630 &ConstructAZIndexFile($var{'dirmfiles'}, 'short', 'global', @names);
631 &ConstructAZIndexFile($var{'dirmfiles'}, 'long', 'global', @names);
632 $indexcreated+=2;
633
634 # if contents.m were created or updated, the dependency matrices should
635 # be updated as well
636 if ($var{'writecontentsm'} eq 'yes') { &ConstructDependencyMatrixReadFiles('contents');; }
637 }
638
639
640 #========================================================================
641 # Construct the highest level index file
642 #========================================================================
643 sub ConstructHighestIndexFile
644 {
645 local(*IFILE);
646 local($indexfile, $filename);
647
648 # Build the frame layout file, this files includes the layout of the frames
649 # Build the frame layout file name (highest one)
650 $indexfile = $var{'dirhtml'}.$var{'filenametopframe'}.$var{'exthtml'};
651
652 if ($var{'frames'} eq 'yes') {
653
654 open(IFILE,">$indexfile") || die("Cannot open frame layout file $indexfile\n");
655
656 # Write the header of frame file
657 print IFILE "$TextDocTypeFrame\n<html>\n<head>\n$var{'codeheadmeta'}\n$TextMetaCharset\n";
658 print IFILE " <title>$var{'texttitleframelayout'}</title>\n";
659 print IFILE "</head>\n";
660
661 # definition of 2 frames, left the tree of directories,
662 # right the index of that directory or the docu of a file
663 print IFILE "<frameset cols=\"25%,75%\">\n";
664 print IFILE " <frame src=\"$var{'filenamedirshort'}$var{'exthtml'}\" name=\"$GlobalNameFrameMainLeft\" />\n";
665 print IFILE " <frame src=\"$var{'filenameindexshortglobal'}$var{'filenameextensionframe'}$var{'exthtml'}\" name=\"$GlobalNameFrameMainRight\" />\n"; print IFILE "</frameset>\n";
666
667 print IFILE "</html>\n";
668
669 close(IFILE);
670
671 if ($opt_silent) { print "\r"; }
672 print " Frame layout file created: $indexfile\t";
673 if (!$opt_silent) { print "\n"; }
674 }
675
676 for($irun=0; $irun <= 2; $irun++) {
677 # Build the top directory index file, these files include the directory tree
678 # Build the directory tree index file name
679
680 # Create no directory file for contents, when no contents to use
681 if (($irun == 2) && ($var{'usecontentsm'} eq 'no')) { next; }
682
683 # Assign the correct index file name
684 if ($irun == 0) { $filename = $var{'filenamedirshort'}; }
685 elsif ($irun == 1) { $filename = $var{'filenamedirlong'}; }
686 elsif ($irun == 2) { $filename = $var{'filenamedircontents'}; }
687
688 $indexfile = $var{'dirhtml'}.$filename.$var{'exthtml'};
689
690 open(IFILE,">$indexfile") || die("Cannot open directory tree index file $indexfile\n");
691 # Write header of HTML file
692 print IFILE "$TextDocTypeHTML\n<html>\n<head>\n$var{'codeheadmeta'}\n$TextMetaCharset\n$var{'csslink'}\n";
693
694 if ($var{'texttitleindexalldirs'} eq '') {
695 print IFILE "<title>Index of Directories of $var{'dirmfiles'}</title>\n";
696 } else {
697 print IFILE "<title>$var{'texttitleindexalldirs'}</title>\n";
698 }
699
700 if ($var{'frames'} eq 'yes') {
701 print IFILE "<base target=\"$GlobalNameFrameMainRight\" />\n";
702 }
703
704 print IFILE "</head>\n";
705 print IFILE "<body $var{'codebodyindex'}>\n";
706 print IFILE "<div id=\"matlabdoc\">\n";
707 if ($var{'textheaderindexalldirs'} eq '') {
708 print IFILE "<h1 $var{'codeheader'}>Index of Directories of <em>$var{'dirmfiles'}</em></h1>\n";
709 } else {
710 print IFILE "<h1 $var{'codeheader'}>$var{'textheaderindexalldirs'}</h1>\n";
711 }
712 print IFILE "<p>\n";
713
714 if ($var{'frames'} eq 'yes') {
715 if ($irun == 0) { print IFILE "<strong>short</strong>\n"; }
716 else { print IFILE "<a href=\"$var{'filenamedirshort'}$var{'exthtml'}\" target=\"$GlobalNameFrameMainLeft\">short</a>\n"; }
717 if ($irun == 1) { print IFILE " | <strong>long</strong>\n"; }
718 else { print IFILE " | <a href=\"$var{'filenamedirlong'}$var{'exthtml'}\" target=\"$GlobalNameFrameMainLeft\">long</a>\n"; }
719 if ($var{'usecontentsm'} eq 'yes') {
720 if ($irun == 2) { print IFILE " | <strong>contents</strong>\n"; }
721 else { print IFILE " | <a href=\"$var{'filenamedircontents'}$var{'exthtml'}\" target=\"$GlobalNameFrameMainLeft\">contents</a>\n"; }
722 }
723 } else {
724 if ($irun == 0) { print IFILE "<strong>short</strong>\n"; }
725 else { print IFILE "<a href=\"$var{'filenamedirshort'}$var{'exthtml'}\">short</a>\n"; }
726 if ($irun == 1) { print IFILE " | <strong>long</strong>\n"; }
727 else { print IFILE " | <a href=\"$var{'filenamedirlong'}$var{'exthtml'}\">long</a>\n"; }
728 if ($var{'usecontentsm'} eq 'yes') {
729 if ($irun == 2) { print IFILE " | <strong>contents</strong>\n"; }
730 else { print IFILE " | <a href=\"$var{'filenamedircontents'}$var{'exthtml'}\">contents</a>\n"; }
731 }
732 }
733
734 print IFILE "</p><br />\n\n";
735 print IFILE "<ul>\n";
736
737 # go through all directories and create a list entry for each one,
738 # depending on recursion level create sublists
739 $prevrecdeeplevel = 0;
740 foreach $name (@alldirectories) {
741 $actrecdeeplevel = $dirnamerecdeep{$name};
742 for( ; $prevrecdeeplevel < $actrecdeeplevel; $prevrecdeeplevel++ ) { print IFILE "<ul>\n"; }
743 for( ; $prevrecdeeplevel > $actrecdeeplevel; $prevrecdeeplevel-- ) { print IFILE "</ul>\n"; }
744 if ($irun == 0) { $indexfilenameused = $var{'filenameindexshortlocal'}.$var{'filenameextensionframe'}; }
745 elsif ($irun == 1) { $indexfilenameused = $var{'filenameindexlonglocal'}.$var{'filenameextensionframe'}; }
746 elsif ($irun == 2) { $indexfilenameused = $contentsname{$name}; }
747 else { die "ConstructHighestIndexFile: Unknown value of irun"; }
748 if ($dirnumbermfiles{$name} > 0) {
749 # producetree no
750 # if ($var{'producetree'} eq 'no') { $dirnamehere = ''; }
751 # else { $dirnamehere = '$dirnamerelpath{$name}'; }
752 # print IFILE "<LI><A HREF=\"$dirnamehere$indexfilenameused_$dirnamesingle{$name}$var{'exthtml'}\">$dirnamesingle{$name}</A>\n";
753 print IFILE "<li><a href=\"$dirnamerelpath{$name}$indexfilenameused$dirnamesingle{$name}$var{'exthtml'}\">$dirnamesingle{$name}</a></li>\n";
754 } else {
755 # print directories with no m-files inside not
756 # print IFILE "<li>$dirnamesingle{$name}</li>\n";
757 }
758 }
759 $actrecdeeplevel = 0;
760 for( ; $prevrecdeeplevel > $actrecdeeplevel; $prevrecdeeplevel-- ) { print IFILE "</ul>\n"; }
761 print IFILE "</ul>\n<br />$var{'codehr'}\n";
762
763 # Include info about author from authorfile
764 &WriteFile2Handle($var{'authorfile'}, IFILE);
765
766 print IFILE "<!--navigate-->\n";
767 print IFILE "<!--copyright-->\n";
768 print IFILE "</div>\n</body>\n</html>\n";
769
770 close(IFILE);
771
772 if ($opt_silent) { print "\r"; }
773 print " Directory - Indexfile created: $indexfile\t";
774 if (!$opt_silent) { print "\n"; }
775 }
776 }
777
778
779 #========================================================================
780 # Construct the A-Z index file (global/local and/or short/long)
781 #========================================================================
782 sub ConstructAZIndexFile
783 {
784 local($LocalActDir, $LocalShortLong, $LocalGlobalLocal, @localnames) = @_;
785 local(*IFILE);
786 local($name, $indexfilename, $dirpath);
787 local($firstletter, $firstone);
788
789 if ($debug > 2) { print "localnames in AZ small: @localnames\n"; print " ActDir in A-Z: $LocalActDir\n"; }
790
791 # extract filename of index file from parameters of function
792 if ($LocalShortLong eq 'short') {
793 if ($LocalGlobalLocal eq 'global') { $indexfilename = $var{'filenameindexshortglobal'}; }
794 elsif ($LocalGlobalLocal eq 'local') { $indexfilename = $var{'filenameindexshortlocal'}; }
795 else { die "wrong parameter for LocalGlobalLocal in ConstructAZIndexFile: $LocalGlobalLocal."; }
796 } elsif ($LocalShortLong eq 'long') {
797 if ($LocalGlobalLocal eq 'global') { $indexfilename = $var{'filenameindexlongglobal'}; }
798 elsif ($LocalGlobalLocal eq 'local') { $indexfilename = $var{'filenameindexlonglocal'}; }
799 else { die "wrong parameter for LocalGlobalLocal in ConstructAZIndexFile: $LocalGlobalLocal."; }
800 } else { die "wrong parameter for LocalShortLong in ConstructAZIndexFile: $LocalShortLong."; }
801
802 # producetree no
803 # if ($var{'producetree'} eq 'no') { $dirnamehere = ''; }
804 # else { $dirnamehere = '$dirnamerelpath{$LocalActDir}'; }
805 # Build the index file name
806 # handle the global index file case separately (no extra directory name in file)
807 # the local index file name must be extended by the name of the directory
808 if ($LocalGlobalLocal eq 'global') { $extradirfilename = ''; }
809 else { $extradirfilename = $dirnamesingle{$LocalActDir}; }
810 $indexfile = $var{'dirhtml'}.$dirnamerelpath{$LocalActDir}.$indexfilename.$var{'filenameextensionindex'}.$extradirfilename.$var{'exthtml'};
811
812 if ($LocalShortLong eq 'short' and $extradirfilename eq '' and $var{'frames'} ne 'yes') {
813 # With no frames and no subdir path, this must go in the
814 # top-level index file instead
815 $indexfile = $var{'dirhtml'}.$var{'filenametopframe'}.$var{'exthtml'};
816 }
817
818 if ($debug > 2) { print " indexfilename (a-z small): $indexfile\n"; }
819
820 open(IFILE,">$indexfile") || die("Cannot open index file $indexfile: $!\n");
821
822 # Write the header of HTML file
823 print IFILE "$TextDocTypeHTML\n<html>\n<head>\n$var{'codeheadmeta'}\n$TextMetaCharset\n$var{'csslink'}\n";
824
825 my $dirToPrint = $LocalActDir;
826 $dirToPrint =~ s,^./,,;
827
828 if ($var{'texttitleindex'} eq '') {
829 print IFILE "<title>Index of Matlab Files in Directory $dirToPrint</title>\n";
830 } else {
831 if ($LocalGlobalLocal eq 'global') { print IFILE "<title>$var{'texttitleindex'}</title>\n"; }
832 else { print IFILE "<title>$var{'texttitleindex'} in Directory $dirToPrint</title>\n"; }
833 }
834
835 if ($var{'frames'} eq 'yes') {
836 print IFILE "<base target=\"$GlobalNameFrameMainRight\" />\n";
837 }
838 print IFILE "</head>\n";
839
840 print IFILE "<body $var{'codebodyindex'}>\n";
841 print IFILE "<div id=\"matlabdoc\">\n";
842 if ($var{'textheaderindex'} eq '') {
843 print IFILE "<h1 $var{'codeheader'}>Index of Matlab Files in Directory $dirToPrint</h1>\n";
844 } else {
845 if ($LocalGlobalLocal eq 'global') { print IFILE "<h1 $var{'codeheader'}>$var{'textheaderindex'}</h1>\n"; }
846 else { print IFILE "<h1 $var{'codeheader'}>$var{'textheaderindex'} in Directory $dirToPrint</h1>\n"; }
847 }
848
849 # include links to indexes
850 &ConstructLinks2Index(IFILE, $dirnamerelpathtoindex{$LocalActDir}, $LocalActDir, $LocalGlobalLocal);
851
852 # Collect the starting letters of m files in this directory or all m-files
853 for('a'..'z') { undef @{$_}; }
854 foreach $name (@localnames) {
855 if (! ($mfilename{$name} =~ /contents/i)) {
856 $firstletter = substr($mfilename{$name}, 0, 1);
857 # convert first letter always to lower case
858 # needed for reference to lower and upper case m-files
859 $firstletter = "\L$firstletter\E";
860 push(@{$firstletter}, $name);
861 }
862 }
863
864 if ($LocalShortLong eq 'short') {
865 # begin create short index
866 print IFILE "<table width=\"100%\">\n";
867
868 for('a'..'z') {
869 # print " $_: @{$_}\n";
870 $numberofletter = $#{$_}+1;
871 $cols = 3;
872 if ($numberofletter > 0) {
873 print IFILE "\n<tr><td><br/><strong><a name=\"\U$_\E$_\"></a><span class=\"an\">\U$_\E</span></strong></td></tr>\n";
874 for ($count = 0; $count < $numberofletter; $count++) {
875 if (($count % $cols) == 0) {
876 if ($count > 0) {
877 print IFILE "</tr><tr>\n";
878 }
879 print IFILE "<tr><td></td>";
880 }
881 $name = @{$_}[$count];
882 if ($LocalGlobalLocal eq 'global') { $dirpath = $hfilerelpath{$name}; } else { $dirpath = ""; }
883 print IFILE "<td><a href=\"$dirpath$mfilename{$name}$var{'exthtml'}\">$mfilename{$name}</a></td>";
884 }
885
886 print IFILE "</tr>\n";
887
888 # $numberhalf = ($numberofletter + 1 - (($numberofletter+1) % 2))/2;
889 # if ($debug > 2) { print " $_: @{$_} \t $numberhalf \t $numberofletter\n"; }
890 # for($count = 0; $count < $numberhalf; $count++) {
891 # $name = @{$_}[$count];
892 # if ($LocalGlobalLocal eq 'global') { $dirpath = $hfilerelpath{$name}; } else { $dirpath = ""; }
893 # print IFILE "<tr><td width=\"50%\"><a href=\"$dirpath$mfilename{$name}$var{'exthtml'}\">$mfilename{$name}</a></td>";
894 # if (($count + $numberhalf) < $numberofletter) {
895 # $name = @{$_}[$count + $numberhalf];
896 # if ($LocalGlobalLocal eq 'global') { $dirpath = $hfilerelpath{$name}; } else { $dirpath = ""; }
897 # print IFILE "<td width=\"50%\"><a href=\"$dirpath$mfilename{$name}$var{'exthtml'}\">$mfilename{$name}</a></td></tr>\n";
898 # } else {
899 # print IFILE "<td width=\"50%\"></td></tr>\n";
900 # }
901 # }
902 }
903 }
904 print IFILE "</table>\n<br />$var{'codehr'}\n";
905
906 } elsif ($LocalShortLong eq 'long') {
907 # begin create long index
908 print IFILE "<table width=\"100%\">\n";
909 print IFILE "<tr><th>Name</th><th>Synopsis</th></tr>\n";
910
911 for('a'..'z') {
912 # print " $_: @{$_}\n";
913 $numberofletter = $#{$_}+1;
914 if ($numberofletter > 0) {
915 $firstone = 1;
916 foreach $name (@{$_}) {
917 if ($debug > 1) { print " AZinforeach1: $name \t\t $hfilerelpath{$name} \t\t $dirnamerelpath{$LocalActDir}\n"; }
918 if ($LocalGlobalLocal eq 'global') { $dirpath = $hfilerelpath{$name}; } else { $dirpath = ""; }
919 if (! ($mfilename{$name} =~ /contents/i)) {
920 if ($firstone == 1) { print IFILE "\n<tr><td colspan=\"2\"><br /><strong><a name=\"\U$_\E$_\"></a><span class=\"an\">\U$_\E</span></strong></td></tr>\n"; $firstone = 0; }
921 print IFILE "<tr><td valign=\"top\"><a href=\"$dirpath$mfilename{$name}$var{'exthtml'}\">$mfilename{$name}</a></td><td>$apropos{$name}</td></tr>\n";
922 }
923 }
924 }
925 }
926 print IFILE "</table>\n<br />$var{'codehr'}\n";
927 } else { die "wrong parameter for LocalShortLong in ConstructAZIndexFile: $LocalShortLong."; }
928
929 # Include info about author from authorfile
930 &WriteFile2Handle($var{'authorfile'}, IFILE);
931
932 print IFILE "<!--navigate-->\n";
933 print IFILE "<!--copyright-->\n";
934 print IFILE "</div>\n</body>\n</html>\n";
935
936 close(IFILE);
937
938 if ($opt_silent) { print "\r"; }
939 print " Indexfile small (A-Z) created: $indexfile\t";
940 if (!$opt_silent) { print "\n"; }
941
942
943 # Build the A-Z jump index file name
944 # handle the global index file case separately (no extra directory name in file)
945 if ($LocalGlobalLocal eq 'global') { $extradirfilename = ''; }
946 else { $extradirfilename = $dirnamesingle{$LocalActDir}; }
947
948 if ($var{'frames'} eq 'yes') {
949
950 $indexfile = $var{'dirhtml'}.$dirnamerelpath{$LocalActDir}.$indexfilename.$var{'filenameextensionjump'}.$extradirfilename.$var{'exthtml'};
951 if ($debug > 2) { print " indexfilename (a-z jump): $indexfile\n"; }
952 open(IFILE,">$indexfile") || die("Cannot open jump index file $indexfile: $!\n");
953
954 # Write the header of HTML file
955 print IFILE "$TextDocTypeHTML\n<html>\n<head>\n$var{'codeheadmeta'}\n$TextMetaCharset\n$var{'csslink'}\n";
956
957 if ($var{'texttitleindex'} eq '') {
958 print IFILE "<title>A-Z jump index in directory $dirToPrint</title>\n";
959 } else {
960 if ($LocalGlobalLocal eq 'global') { print IFILE "<title>$var{'texttitleindex'}</title>\n"; }
961 else { print IFILE "<title>$var{'texttitleindex'} in Directory $dirToPrint</title>\n"; }
962 }
963
964 if ($var{'frames'} eq 'yes') {
965 print IFILE "<base target=\"$GlobalNameFrameAZIndexsmall\" />\n";
966 }
967 print IFILE "</head>\n";
968 print IFILE "<body $var{'codebodyindex'}>\n";
969 print IFILE "<div id=\"matlabdoc\">\n";
970
971 # Write the A-Z jump line, generate link for letters with files starting with this letter
972 # and only letters for no files starting with this letter
973 # use previously generated arrays with names of files sorted by starting letter
974 for('a'..'z') {
975 $numberofletter = $#{$_}+1;
976 if ($numberofletter > 0) {
977 print IFILE "<strong><a href=\"$indexfilename$var{'filenameextensionindex'}$extradirfilename$var{'exthtml'}#\U$_\E$_\">\U$_\E</a> </strong>\n";
978 } else {
979 print IFILE "\U$_\E \n";
980 }
981 }
982
983 print IFILE "</div></body>\n</html>\n";
984
985 close(IFILE);
986
987 if ($opt_silent) { print "\r"; }
988 print " Indexfile small (A-Z jump) created: $indexfile\t";
989 if (!$opt_silent) { print "\n"; }
990 }
991
992
993 # Build the frame layout file, this file includes the layout of the frames
994 # Build the frame layout file name (for small/compact A-Z index)
995 # handle the global index file case separately (no extra directory name in file)
996 if ($LocalGlobalLocal eq 'global') { $extradirfilename = ''; }
997 else { $extradirfilename = $dirnamesingle{$LocalActDir}; }
998
999 if ($var{'frames'} eq 'yes') {
1000
1001 $indexfile = $var{'dirhtml'}.$dirnamerelpath{$LocalActDir}.$indexfilename.$var{'filenameextensionframe'}.$extradirfilename.$var{'exthtml'};
1002 if ($debug > 2) { print " indexfilename (a-z frame): $indexfile\n"; }
1003
1004 open(IFILE,">$indexfile") || die("Cannot open jump index frame file $indexfile: $!\n");
1005
1006 # Write the header of Frame file
1007 print IFILE "$TextDocTypeHTML\n<html>\n<head>\n$var{'codeheadmeta'}\n$TextMetaCharset\n$var{'csslink'}\n";
1008
1009 if ($var{'texttitleindex'} eq '') {
1010 print IFILE "<title>Index of Matlab Files in Directory $dirToPrint</title>\n";
1011 } else {
1012 if ($LocalGlobalLocal eq 'global') { print IFILE "<title>$var{'texttitleindex'}</title>\n"; }
1013 else { print IFILE "<title>$var{'texttitleindex'} in Directory $dirToPrint</title>\n"; }
1014 }
1015 print IFILE "</head>\n";
1016
1017 # definition of 2 frames, top the A-Z index, below the jump letter line
1018 print IFILE "<frameset rows=\"90%,10%\">\n";
1019 print IFILE " <frame src=\"$indexfilename$var{'filenameextensionindex'}$extradirfilename$var{'exthtml'}\" name=\"$GlobalNameFrameAZIndexsmall\" />\n";
1020 print IFILE " <frame src=\"$indexfilename$var{'filenameextensionjump'}$extradirfilename$var{'exthtml'}\" name=\"$GlobalNameFrameAZIndexjump\" />\n";
1021 print IFILE "</frameset>\n";
1022
1023 print IFILE "</html>\n";
1024
1025 close(IFILE);
1026
1027 if ($opt_silent) { print "\r"; }
1028 print " Frame layout file created: $indexfile\t";
1029 if (!$opt_silent) { print "\n"; }
1030 }
1031 }
1032
1033
1034 #========================================================================
1035 # Construct the links to all indexes
1036 #========================================================================
1037 sub ConstructLinks2Index
1038 {
1039 local(*WRITEFILE, $LocalPath2Index, $PathContents, $LocalGlobalLocal) = @_;
1040
1041 # include links to short/long - local/global index and C|contents.m
1042 print WRITEFILE "\n<p>";
1043 print WRITEFILE "$var{'textjumpindexglobal'} ";
1044
1045 if ($var{'frames'} eq 'yes') {
1046 print WRITEFILE "<a href=\"$LocalPath2Index$var{'filenameindexshortglobal'}$var{'filenameextensionframe'}$var{'exthtml'}\">short</a> | ";
1047 print WRITEFILE "<a href=\"$LocalPath2Index$var{'filenameindexlongglobal'}$var{'filenameextensionframe'}$var{'exthtml'}\">long</a>\n";
1048 } else {
1049 print WRITEFILE "<a href=\"$LocalPath2Index$var{'filenametopframe'}$var{'exthtml'}\">short</a> | ";
1050 print WRITEFILE "<a href=\"$LocalPath2Index$var{'filenameindexlongglobal'}$var{'filenameextensionindex'}$var{'exthtml'}\">long</a>\n";
1051 }
1052
1053 if ($LocalGlobalLocal eq 'local') {
1054 if ($var{'usecontentsm'} eq 'yes') {
1055 print WRITEFILE " | <a href=\"$contentsname{$PathContents}$dirnamesingle{$PathContents}$var{'exthtml'}\">Local contents</a>\n";
1056 }
1057 if ($var{'frames'} eq 'yes') {
1058 print WRITEFILE " | $var{'textjumpindexlocal'} ";
1059 print WRITEFILE "<a href=\"$var{'filenameindexshortlocal'}$var{'filenameextensionframe'}$dirnamesingle{$PathContents}$var{'exthtml'}\">short</a> | ";
1060 print WRITEFILE "<a href=\"$var{'filenameindexlonglocal'}$var{'filenameextensionframe'}$dirnamesingle{$PathContents}$var{'exthtml'}\">long</a>\n";
1061 } else {
1062 print WRITEFILE " | $var{'textjumpindexlocal'} ";
1063 print WRITEFILE "<a href=\"$var{'filenameindexshortlocal'}$var{'filenameextensionindex'}$dirnamesingle{$PathContents}$var{'exthtml'}\">short</a> | ";
1064 print WRITEFILE "<a href=\"$var{'filenameindexlonglocal'}$var{'filenameextensionindex'}$dirnamesingle{$PathContents}$var{'exthtml'}\">long</a>\n";
1065 }
1066 }
1067 print WRITEFILE "</p>\n\n";
1068 print WRITEFILE "$var{'codehr'}\n";
1069 }
1070
1071
1072 #========================================================================
1073 # Construct the contents.m files or update
1074 #========================================================================
1075 sub ConstructContentsmFile
1076 {
1077 local($LocalActDir, @localnames) = @_;
1078 local(*CFILE, $name,$newline);
1079 local($contentsfile, $isincontentsonly);
1080 local(@lines, @autoaddlines, @emptylines);
1081 local($autoadd) = 'AutoAdd';
1082 local($autoaddsection) = 0;
1083 local($emptylineflag) = 0;
1084 local(%nameincontents);
1085
1086 # Build the contents file name
1087 $contentsfile = $LocalActDir.$contentsname{$LocalActDir}.$suffix;
1088
1089 if (-e $contentsfile) {
1090 open(CFILE,"<$contentsfile") || die("Cannot open contents file $contentsfile: $!\n");
1091 while (<CFILE>) {
1092 # Search for the specified string pattern
1093 @words = split;
1094 if ((@words >= 3) && ($words[2] eq '-')) {
1095 $isincontentsonly = 0;
1096 foreach $name (@localnames) {
1097 if ($name eq $words[1]) { # old
1098 # if ($mfilename{$name} eq $words[1]) {
1099 $isincontentsonly = 1;
1100 $nameincontents{$name} = 1;
1101 $newline = sprintf("%% %-13s - %s\n", $mfilename{$name}, $apropos{$name});
1102 push(@lines, $newline);
1103 }
1104 }
1105 # issue a warning, if file is in contents, but not as file in the directory
1106 if ($isincontentsonly == 0) {
1107 print "\rConstructContents: Obsolete entry $words[1] in $contentsfile ! Entry not used.\n";
1108 }
1109 } else {
1110 # look for the AutoAdd section, should be the second word
1111 if ((@words >= 2) && ($words[1] eq $autoadd)) { $autoaddsection = 1; }
1112 # push the red line in an array
1113 push(@lines, $_);
1114 }
1115 }
1116 close(CFILE);
1117 } else {
1118 $newline = "% MATLAB Files in directory $LocalActDir\n%\n";
1119 push(@lines, $newline);
1120
1121 }
1122
1123 # collect the file names, that were not included in original C|contents.m
1124 foreach $name (@localnames) {
1125 if (! defined $nameincontents{$name}) {
1126 if (! ($mfilename{$name} =~ /contents/i)) {
1127 $newline = sprintf("%% %-13s - %s\n", $mfilename{$name}, $apropos{$name});
1128 push(@autoaddlines, $newline);
1129 }
1130 }
1131 }
1132
1133 # write/update C|contents.m only if variable is set
1134 if ($var{'writecontentsm'} eq 'yes') {
1135 unlink($contentsfile);
1136 open(CFILE,">$contentsfile") || die("Cannot open contents file $contentsfile: $!\n");
1137 # write old C|contents.m or header of new file, as long as comment lines
1138 foreach $line (@lines) {
1139 if ($emptylineflag == 0) {
1140 if ($line =~ /^\s*%/) { print CFILE $line; }
1141 else { $emptylineflag = 1; push(@emptylines, $line); }
1142 } else { push(@emptylines, $line); }
1143 }
1144 # add header of AutoAdd section
1145 if (($autoaddsection == 0) && (@autoaddlines > 0)) { print CFILE "%\n% $autoadd\n"; }
1146 # add autoadd section lines (previously undocumented files
1147 foreach $line (@autoaddlines) { print CFILE $line; }
1148 # add tail of original C|contents.m (everything behind first non-comment line)
1149 foreach $line (@emptylines) { print CFILE $line; }
1150 print CFILE "\n";
1151 close CFILE;
1152 if ($opt_silent) { print "\r"; }
1153 print " Contents file created/updated: $contentsfile\t";
1154 if (!$opt_silent) { print "\n"; }
1155 }
1156 }
1157
1158
1159 #========================================================================
1160 # Replace found special characters with their HTMl Entities
1161 #========================================================================
1162 sub SubstituteHTMLEntities {
1163 local($_) = @_;
1164
1165 # Replace & <-> &amp; < <-> &lt; > <-> &gt; " <-> &quot;
1166 s/&/&amp;/g; s/\</&lt;/g; s/\>/&gt;/g; s/\"/&quot;/g;
1167 return $_;
1168 }
1169
1170 #========================================================================
1171 # Replace found m-filenamestring with full link.
1172 #========================================================================
1173 sub SubstituteName2Link {
1174 local($_, $funname) = @_;
1175 local($refstr1, $refstr2, $reffound);
1176
1177 # Look for something matching in the line
1178 if ( /(\W+)($funname)(\W+)/i ) {
1179 $reffound = $2;
1180 $refstr1 = "<a class=\"mfun\" href=\"$hfileindexpath{$name}$hfilerelpath{$funname}$mfilename{$funname}$var{'exthtml'}\">";
1181 $refstr2 = "<\/a>";
1182 # Do links only for exact case match
1183 if ( ($var{'links2filescase'} eq 'exact') || ($var{'links2filescase'} eq 'exactvery') ) {
1184 if ( /(\W+)($funname)(\W+)/g ) {
1185 s/(\W+)($funname)(\W+)/$1$refstr1$funname$refstr2$3/g;
1186 }
1187 else {
1188 # Print info for not matching case in references, good for check up of files
1189 if ( ($var{'links2filescase'} eq 'exactvery') ) {
1190 print "Diff in case found: $funname (case of file name) <-> $reffound (case in source code)\n";
1191 print " (source line) $_ \n";
1192 }
1193 }
1194 }
1195 # Do links for exact match and additionally for all upper case (often used in original matlab help text)
1196 elsif ( ($var{'links2filescase'} eq 'exactupper') ) {
1197 s/(\W+)($funname)(\W+)/$1$refstr1$2$refstr2$3/g;
1198 $funname2 = "\U$funname\E";
1199 s/(\W+)($funname2)(\W+)/$1$refstr1$2$refstr2$3/g;
1200 }
1201 # Do links for all case mixes, this calls for trouble under LINUX/UNIX
1202 else { #elsif ( ($var{'links2filescase'} eq 'all') )
1203 s/(\W+)($funname)(\W+)/$1$refstr1$2$refstr2$3/ig;
1204 }
1205 }
1206
1207 return $_;
1208 }
1209
1210 #========================================================================
1211 # Construct the html files for each matlab file.
1212 # Need to reread each matlab file to find the help text.
1213 # Note that we can't do this in a single loop because sometimes
1214 # the help text maybe before the function declaration.
1215 #========================================================================
1216 sub ConstructHTMLFiles
1217 {
1218 local(*MFILE);
1219 local(*HFILE);
1220
1221 local($filescreated) = 0;
1222 local($functionline);
1223
1224 foreach $name (@names) {
1225 # Create cross reference information already here, used for keywords as well
1226 # Construct list of referenced functions
1227 @xref = @{'depcalls'.$name}; # the functions, that this m-file calls
1228 @yref = @{'depcalled'.$name}; # the functions, that this m-file is called from
1229 # print " depcalls: @{'depcalls'.$name}\n depcalled: @{'depcalled'.$name}\n";
1230 # foreach $cname (@names) { next if $cname eq $name; push(@yref,$cname) if grep(/$name/,@{'depcalls'.$cname}); }
1231
1232
1233 # Open m-file and html-file
1234 open(MFILE,"<$mfile{$name}");
1235 open(HFILE,">$hfile{$name}");
1236
1237 # Write the header of HTML file
1238 print HFILE "$TextDocTypeHTML\n<html>\n<head>\n$var{'codeheadmeta'}\n$TextMetaCharset\n$var{'csslink'}\n";
1239
1240 # Write meta tags: use apropos (one line function description) for description
1241 # and cross reference function names for keywords (any better ideas?)
1242 print HFILE "<meta name=\"description\" content=\" $apropos{$name} \" />\n";
1243 print HFILE "<meta name=\"keywords\" content=\" @xref @yref \" />\n";
1244
1245 # Write Title and start body of html-file
1246 print HFILE "<title>$var{'texttitlefiles'} $mfilename{$name}</title>\n</head>\n";
1247 print HFILE "<body $var{'codebodyfiles'}>\n";
1248 print HFILE "<div id=\"matlabdoc\">\n";
1249 print HFILE "<h1 $var{'codeheader'}>$var{'textheaderfiles'} $mfilename{$name}</h1>\n";
1250
1251 # http://test.soundsoftware.ac.uk/cannam/projects/smallbox/repository/annotate/DL/RLS-DLA/SolveFISTA.m
1252 # print HFILE "<a href=\"" . $hfileindexpath{$name} . "../../projects/smallbox/repository/annotate/" . $mfiledir{$name} . $mfilename{$name} . ".m\">View in repository</a>\n";
1253
1254 print HFILE "$var{'codehr'}\n";
1255
1256 # include links to short/long - local/global index and C|contents.m
1257 &ConstructLinks2Index(HFILE, $hfileindexpath{$name}, $mfiledir{$name}, 'local');
1258
1259 # If this is a function, then write out the first line as a synopsis
1260 if ($mtype{$name} eq "function") {
1261 print HFILE "<h2 $var{'codeheader'}>Function Synopsis</h2>\n";
1262 print HFILE "<pre>$synopsis{$name}</pre>\n$var{'codehr'}\n";
1263 }
1264
1265 # Look for the matlab help text block
1266 $functionline = "\n";
1267 do {
1268 $_ = <MFILE>;
1269 # remember functionline, if before help text block
1270 if (/^\s*function/) { $functionline = $_; }
1271 } until (/^\s*%/ || eof);
1272 if (! (eof(MFILE))) {
1273 print HFILE "<h2 $var{'codeheader'}>Help text</h2>\n";
1274 print HFILE "<pre>\n";
1275 while (/^\s*%/) {
1276 # First remove leading % and white space, then Substitute special characlers
1277 s/^\s*%//;
1278 $_ = &SubstituteHTMLEntities($_);
1279
1280 # check/create cross references
1281 foreach $funname (@{'all'.$name}) {
1282 if ($funname =~ /simulink/) { print "\n Simulink - Filename: $name; scanname: $funname\n"; }
1283 next if $funname eq $name;
1284 $_ = &SubstituteName2Link($_, $funname);
1285 }
1286 print HFILE $_;
1287 if (! eof) { $_ = <MFILE>; }
1288 }
1289 print HFILE "</pre>\n$var{'codehr'}\n";
1290 }
1291
1292 # Write the cross reference information
1293 if (@xref || @yref) {
1294 print HFILE "<h2 $var{'codeheader'}>Cross-Reference Information</H2>\n";
1295 print HFILE "<table border=\"0\" width=\"100%\">\n<tr align=\"left\">\n<th width=\"50%\">";
1296 if (@xref) {
1297 print HFILE "This $mtype{$name} calls";
1298 }
1299 print HFILE "</th>\n<th width=\"50%\">";
1300 if (@yref) {
1301 print HFILE "This $mtype{$name} is called by";
1302 }
1303 print HFILE "</th>\n</tr>\n<tr valign=\"top\"><td>";
1304 if (@xref) {
1305 print HFILE "\n<ul>\n";
1306 foreach $cname (sort @xref) {
1307 print HFILE "<li><a class=\"mfun\" href=\"$hfileindexpath{$name}$hfilerelpath{$cname}$mfilename{$cname}$var{'exthtml'}\">$mfilename{$cname}</a></li>\n";
1308 }
1309 print HFILE "</ul>\n";
1310 }
1311 print HFILE "</td><td>";
1312 if (@yref) {
1313 print HFILE "\n<ul>\n";
1314 foreach $cname (sort @yref) {
1315 print HFILE "<li><a class=\"mfun\" href=\"$hfileindexpath{$name}$hfilerelpath{$cname}$mfilename{$cname}$var{'exthtml'}\">$mfilename{$cname}</a></li>\n";
1316 }
1317 print HFILE "</ul>\n";
1318 }
1319 print HFILE "</td>\n</tr>\n</table>\n";
1320 print HFILE "$var{'codehr'}\n";
1321 }
1322
1323 # Include source text if requested
1324 if (($var{'includesource'} eq 'yes') && (! ($mfilename{$name} =~ /^contents$/i))) {
1325 print HFILE "<h2 $var{'codeheader'}>Listing of $mtype{$name} $mfilename{$name}</h2>\n";
1326 seek(MFILE,0,0);
1327 print HFILE "<pre>\n";
1328 $IsStillHelp = 2;
1329 print HFILE $functionline; # functionline from scanning of help
1330 while (<MFILE>) {
1331 if ($IsStillHelp == 2) {
1332 next if (/^\s*$/);
1333 next if (/^\s*function/);
1334 if (/^\s*%/) { $IsStillHelp = 1; next; }
1335 } elsif ($IsStillHelp == 1) {
1336 next if (/^\s*%/);
1337 $IsStillHelp = 0;
1338 }
1339
1340 # Substritute special characters
1341 $_ = &SubstituteHTMLEntities($_);
1342
1343 # check for comment in line and format with css em
1344 s/^(.*)%(.*?)([\s\r\n]+)$/$1<em class=\"mcom\">%$2<\/em>$3/;
1345
1346 # check/create cross references
1347 foreach $funname (@{'all'.$name}) {
1348 next if $funname eq $name;
1349 $_ = &SubstituteName2Link($_, $funname);
1350 }
1351 print HFILE $_;
1352 }
1353 print HFILE "</pre>\n$var{'codehr'}\n";
1354 }
1355
1356 # Include info about author from authorfile
1357 &WriteFile2Handle($var{'authorfile'}, HFILE) ;
1358
1359 print HFILE "<!--navigate-->\n";
1360 print HFILE "<!--copyright-->\n";
1361 print HFILE "</div>\n</body>\n</html>\n";
1362 close(MFILE);
1363 close(HFILE);
1364
1365 # Print name of finished file
1366 if ($opt_silent) { print "\r"; }
1367 print " HTML-File created: $hfile{$name}\t";
1368 if (!$opt_silent) { print "\n"; }
1369 $filescreated++;
1370 }
1371
1372 print "\n$PROGRAM: $indexcreated index and $filescreated files created.\n";
1373 }
1374
1375 #========================================================================
1376 # Function: CheckFileName
1377 # Purpose: .
1378 #========================================================================
1379 sub CheckFileName {
1380 local($filename, $description) = @_;
1381 local(*CHECKFILE);
1382
1383 open(CHECKFILE,"<$filename") || do {
1384 if ($description eq '') {$description = 'file';}
1385 # if (!$opt_silent) { print "Cannot open $description $filename: $!\n"; }
1386 print "Cannot open $description $filename: $!\n";
1387 return 1;
1388 };
1389 close(CHECKFILE);
1390 return 0;
1391
1392 }
1393
1394 #========================================================================
1395 # Function: CheckDirName
1396 # Purpose: .
1397 #========================================================================
1398 sub CheckDirName {
1399 local($dirname, $description) = @_;
1400 local(*CHECKDIR);
1401
1402 opendir(CHECKDIR,"$dirname") || die ("Cannot open $description directory $dirname: $!\n");
1403 closedir(CHECKDIR);
1404 }
1405
1406 #========================================================================
1407 # Function: WriteFile2Handle
1408 # Purpose: .
1409 #========================================================================
1410 sub WriteFile2Handle {
1411 local($filename, *WRITEFILE) = @_;
1412 local(*READFILE);
1413
1414 if ($filename ne '') {
1415 open(READFILE,"<$filename");
1416 @filecontents = <READFILE>;
1417 close(READFILE);
1418 print WRITEFILE "@filecontents\n";
1419 # if (!$opt_silent) {print " Contents of $filename added\n"};
1420 }
1421 }
1422
1423
1424 #========================================================================
1425 # Function: GetConfigFile
1426 # Purpose: Read user's configuration file, if such exists.
1427 #========================================================================
1428 sub GetConfigFile
1429 {
1430 local($filename) = @_;
1431 local(*CONFIG);
1432 local($value);
1433
1434 if (&CheckFileName($filename, 'configuration file')) {
1435 # if (!$opt_silent) { print " Proceeding using built-in defaults for configuration.\n"; }
1436 print " Proceeding using built-in defaults for configuration.\n";
1437 return 0;
1438 };
1439
1440 open(CONFIG,"< $filename");
1441 while (<CONFIG>) {
1442 s/#.*$//;
1443 next if /^\s*$/o;
1444
1445 # match keyword: process one or more arguments
1446 # keyword set
1447 if (/^\s*set\s+(\S+)\s*=\s*(.*)/) {
1448 # setting a configuration variable
1449 if (defined $var{$1}) {
1450 $var{$1} = $2;
1451 if ($debug > 3) { print "$1: $var{$1}\n"; }
1452 }
1453 else {
1454 print "$PROGRAM: unknown variable `$1' in configuration file\n"
1455 }
1456 } else {
1457 chop($_);
1458 print "$PROGRAM: unknown keyword in configuration file in line: `$_'\n"
1459 }
1460 }
1461 close CONFIG;
1462 1;
1463 }
1464
1465
1466 #------------------------------------------------------------------------
1467 # DisplayHelp - display help text using -h or -help command-line switch
1468 #------------------------------------------------------------------------
1469 sub DisplayHelp
1470 {
1471 $help=<<EofHelp;
1472 $PROGRAM v$VERSION - generate html documentation from Matlab m-files
1473
1474 Usage: $PROGRAM [-h] [-c config_file] [-m|dirmfiles matlab_dir] [-d|dirhtml html_dir]
1475 [-i yes|no] [-r yes|no] [-p yes|no] [-quiet|q] [-a authorfile]
1476
1477 $PROGRAM is a perl script that reads each matlab .m file in a directory
1478 to produce a corresponding .html file of help documentation and cross
1479 reference information. An index file is written with links to all of
1480 the html files produced. The options are:
1481
1482 -quiet or -q : be silent, no status information during generation
1483 -help or -h : display this help message
1484 -todo or -t : print the todo list for $PROGRAM
1485 -version or -v : display version
1486
1487 -configfile or -c : name of configuration file (default to $var{'configfile'}).
1488 -dirmfiles or -m : top level directory containing matlab files to generate html for;
1489 default to actual directory.
1490 -dirhtml or -d : top level directory for generated html files;
1491 default to actual directory.
1492
1493 -includesource or -i : Include matlab source in the html documentation [yes|no]
1494 default to yes.
1495 -processtree or -r : create docu for m-file directory and all subdirectories [yes|no];
1496 default to yes.
1497 -producetree or -p : create multi-level docu identical to directory structure
1498 of m-files [yes|no]; default to yes.
1499 -writecontentsm or -w: update or write contents.m files into the matlab source
1500 directories [yes|no]; default to no.
1501
1502 -authorfile or -a : name of file including author information, last element in html;
1503 default to empty.
1504
1505 The command line setting overwrite all other settings (built-in and configuration file).
1506 The configuration file settings overwrite the built-in settings (and not the command
1507 line settings).
1508
1509 Typical usages are:
1510 $PROGRAM
1511 (use default parameters from perl script, if configuration
1512 file is found -> generation of docu, else display of help)
1513
1514 $PROGRAM -dirmfiles matlab -dirhtml html
1515 (generate html documentation for all m-files in directory matlab,
1516 place html files in directory html, use built-in defaults for
1517 all other parameters, this way all m-files in the directory
1518 matlab and below are converted and the generated html-files are
1519 placed in the directory html and below producing the same
1520 directory structure than below matlab)
1521
1522 $PROGRAM -quiet
1523 (use built-in parameters from perl script, if configuration
1524 file is found use these settings as well, do generation,
1525 no display except critical errors, status of conversion and result)
1526
1527 $PROGRAM -m toolbox -dirhtml doc/html -r yes -p no
1528 (convert all m-files in directory toolbox and below and place
1529 the generated html files in directory doc/html, read all m-files
1530 recursively, however, the generated html files are placed in one
1531 directory)
1532
1533 $PROGRAM -m toolbox -dirhtml doc/html -i no -r no
1534 (convert all m-files in directory toolbox and place
1535 the generated html files in directory doc/html, do not read m-files
1536 recursively, do not include source code in documentation)
1537
1538 EofHelp
1539
1540 die "$help";
1541 }
1542
1543 #------------------------------------------------------------------------
1544 # DisplayTodo - display ToDo list using -t or -todo command-line switch
1545 #------------------------------------------------------------------------
1546 sub DisplayTodo
1547 {
1548 $todo=<<EofToDo;
1549 $PROGRAM v$VERSION - ToDo list
1550
1551 o use more than one high level directory
1552
1553 o what should/could be done here???
1554
1555 EofToDo
1556
1557 die "$todo";
1558 }
1559
1560
1561 #------------------------------------------------------------------------
1562 # ListVariables - list all defined variables and their values
1563 #------------------------------------------------------------------------
1564 sub ListVariables
1565 {
1566 local($value);
1567
1568 if ($debug > 0) {
1569 print "List of all variables and their values\n";
1570 foreach (sort keys %var)
1571 {
1572 if ($var{$_} eq '') {
1573 $value = "empty";
1574 } else {
1575 $value = $var{$_};
1576 }
1577 print " $_\n $value\n";
1578 }
1579 print "\n\n";
1580 }
1581 }
1582
1583
1584 __END__
1585 :endofperl