#!/usr/bin/perl $URL = "http://anonimo.isr.ist.utl.pt:8080/~etienne/octave"; ###################################################################### # # This file is a slight modification of Jeffrey C. Kantor's # "mat2html". Basically, the difference lies in recognizing '#' as a # comment character.And there is no more 'p' option. # # I may have broken a few things, but I don't think so. There are a # few glitches. # # I tried to contact Jeffrey C. Kantor, at the address below, without # success, to tell him about this new version of his program. If # anyone knows where to contact him, please let me know. This code was # very well documented and easy to modify. Thank you Jeffrey. # # 2000/03/08 # # Etienne Grossmann # ###################################################################### # READ THE HELP SECTION BELOW FOR INFORMATION ON HOW TO USE THIS SCRIPT. # # To install, simply save this function at oct2html, and make it # executible with # # chmod +x oct2html # # This requires a perl interpreter and access to the standard perl # library. Do not contact me about installing perl, I will ignore # you. Instead, please check out the following standard sites: # # ftp.uu.net gnu/perl* # jpl-decvax.jpl.nasa.gov pub/perl* # archive.cis.ohio-state.edu perl/ # # # Version 1.0 : 12 Jan 1995: Major workover to allow index of # multiple matlab directories. # 10 Jan 1995: Added cross-links to the help text # 9 Jan 1995: Looks for a Readme.m file to put # to put in the directory index. # 9 Jan 1995: Fixed html cross-links # # First posted to comp.soft-sys.matlab on January 9, 1995 # Jeffrey C. Kantor # kantor.1@nd.edu # Copyright (c) Jeffrey C. Kantor 1995. # All rights reserved # # Please feel free to use this script under the conditions of the # standard GNU public license. ###################################################################### # # Subroutines # ###################################################################### # From the standard Perl Library require 'getopts.pl'; require 'ctime.pl'; $CR = '[#%]' ; # Translate special html characters sub htmlchar { s/&/&/g; s/\/>/g; s/\"/"/g; } sub tagline { print HFILE "Produced by oct2html on $date
\n"; print HFILE "Cross-Directory links are: "; if ($opt_g) {print HFILE "ON
\n"} else {print HFILE "OFF
\n"}; } # Assume MFILE and HFILE are open, $headline contains a section # title, and @zref contains cross-reference names # Don't print empty help. sub writehelpblock { do {$_ = } until /^\s*$CR/ || eof; my $help ; if (!eof) { while (/^\s*$CR/) { s/^\s*$CR+//; &htmlchar; foreach $z (@zref) { next if //; $html = "../$hdir{$mdir{$mfile{$z}}}/$z.html"; s/(\W+)($z)(\W+)/\1\2<\/A>\3/ig; # " } $help .= $_ ; $_ = ; } print HFILE "

$headline

\n
\n$help
\n" if $help =~ /\S/ ; } } sub padding { my $s = shift ; my $j = int(length($s)/15)+1 ; my $p = " " x ($j*15 - length($s)) ; return ($j,$p) ; } ###################################################################### # # Command line processing # ###################################################################### # Get the current date string $date = &ctime(time); # Read the command line arguments &Getopts('ghiqH:M:'); warn("WARNING: Options -M and -p are incompatable.\n") if ($opt_M && $opt_p); if (($opt_h) || ($opt_M && $opt_p)) { print <) { chomp; @files = split; @xfiles = (@xfiles,@files); } } elsif ($opt_p) { # Get the octave path print "Running octave -n to get the octave path.\n" if $verbose; open(OCTAVE,"octave -n|") || die("Can't run octave -n to get the path"); do {$_ = } until /OCTAVEPATH/ || eof; while () { last if /^----/; chomp; s/\s*//g; push(@xfiles,$_); } close(OCTAVE); } elsif ($opt_M) { # We need to find the octave directories to search print "Setting octave directory to $opt_M\n" if $verbose; if (-d $opt_M) { @xfiles = ($opt_M); } else { die("Specified -M $opt_M is not a directory\n"); } } else { print "Setting octave directory to the current directory.\n" if $verbose; @xfiles = ("."); } # Now process the list of @xfiles to get a list of .m files @mfiles print "Finding .m files in the search path.\n" if $verbose; undef(@mfiles); foreach (@xfiles) { # chop off any trailing separators, sometimes added by ls s/\/$//; # Add to mfiles if it exists and text file with a .m suffix if ((/\.m$/) && (-e) && (-T)) { push(@mfiles,$_); next; } # If it's a directory, then read it if (-d) { opendir(MDIR,$_) || die("Cannot open directory $_\n"); @files = grep(/\.m$/,readdir(MDIR)); foreach $file (@files) { push(@mfiles,"$_/$file"); } } } $n = $#mfiles + 1; print "Found $n .m files.\n" if $verbose; undef($n); undef(@xfiles); undef($mroot); ###################################################################### # # Parse the octave file names # ###################################################################### # Now we need to parse the mfile names to obtain for each file # $name{$file} - a octave identifier used to search the texts # $mdir{$file} - the directory in which the file is found # $mfile{$name} - look up the first mfile associated with a $name # ###################################################################### ## Re-implement ###################################################### print "Parsing the octave file names.\n" if $verbose; undef(%mdir); foreach (@mfiles) { # Regexp for dir and file ($mdir{$_},$name{$_}) = m|(.*?)/?([^/]*)$| ; $name{$_} =~ s/\.m$//; $mdir{$_} = "." unless exists $mdir{$_} ; $mfile{$name{$_}} = $_ unless exists $mfile{$name{$_}} ; $tmp1{$mdir{$_}} = 1 ; $tmp2{$name{$_}} = 1 ; # printf("222 : %-30s -> %-20s, %-10s\n",$_,$mdir{$_},$name{$_}) ; } @mdirs = sort keys %tmp1 ; @names = sort keys %tmp2 ; $n = $#mdirs + 1; print "Found $n unique octave directories in the search path.\n" if $verbose; undef($n); ###################################################################### # # Read the m-files, and compute cross-reference information # ###################################################################### # Read each file and tabulate the distinct alphanumeric identifiers in # an array of symbols. This is used to compute cross references within # a octave directory. Also scan for: # # synposis - The function declaration line # lookfor - The first line of the help text # mtype - File type, either "function" or "script" # ref - Array of code cross references # # Dependency matrix value $ref{$x,$y} is 1 if $x refers to $y in the # code section. $ref{$x,$y} is 2 if $x refers to $y in the comment # lines. print "Read and compute cross-references among the octave files.\n" if $verbose; foreach $file (@mfiles) { open(MFILE,"<$file") || die("Cannot open $file\n"); print "Reading $file\n" if $verbose; # while () { # chomp; while( ! eof(MFILE) ) { my ($statement,$comment,$all) = ("","",""); while( ! eof(MFILE) && ( $_ = ) =~ /(.*)(\.\.\.|\\)\s*($CR+(.*))?$/ ) { $all .= $_ ; $statement .= $1 ; $comment .= $4 if defined $4; } /(.*?)\s*($CR+(.*))$/ ; $statement .= $1 ; $comment .= $3 if defined $3; $_ = $all . $_ ; # If it's the function declaration line, then store it and skip if (/^\s*function/) { s/^\s*function\s*//; $synopsis{$file} = $_; $mtype{$file} = "function"; # print "synopsis of '$file' is $_\n" ; next; } # Compress multiple [%#]'s to a single [%#] s/$CR+/#/g; # Process comment lines and code lines separately if (/^\s*$CR/) { # cut out comment marker and surrounding white space s/^\s*$CR\s*//; # Store first comment line in lookfor if (!$lookfor{$file}) { # $lookfor{$file} = $_; $lookfor{$file} = $comment; } # Split on nonalphanumerics, canonicalize to lower case tr/A-Z/a-z/; @words = grep(/[a-z]\w*/,split('\W',$_)); grep($hsymbols{$_}++,@words) } else { # Split off and ignore trailing comments ($statement,$comment) = split(/$CR/,$_,2); # Split on nonalphanumerics, preserve case @words = grep(/[a-zA-Z]\w*/,split('\W',$statement)); grep($csymbols{$_}++,@words) } } close MFILE; # Now mark each name that appears in the list of symbols $dir = $mdir{$file}; if ($opt_g) { foreach (grep($csymbols{$_},@names)) { $ref{$file,$mfile{$_}} = 1; } foreach (grep($hsymbols{$_},@names)) { $ref{$file,$mfile{$_}} = 2; } } else { foreach (grep($csymbols{$_},@names)) { $f = $mfile{$_}; next if ($mdir{$f} ne $dir); $ref{$file,$f} = 1; } foreach (grep($hsymbols{$_},@names)) { $f = $mfile{$_}; next if ($mdir{$f} ne $dir); $ref{$file,$f} = 2; } } undef(%csymbols); undef(%hsymbols); } ###################################################################### # # Setup the html directories # ###################################################################### # Create an html subdirectory name for every unique octave directory in the # list @mdirs. The name is constructed using the tail of the directory # prefaced by a unique number. # # $hdir{$mdir} - html subdirectory for octave directory $mdir $x = 1; foreach (@mdirs) { @z = reverse(split("/",$_)); $hdir{$_} = "$x.".@z[0]; $x++; } # for each .m file, name a corresponding .html file foreach (@mfiles) { $hfile{$file} = $name{$_}.".html"; } # Now test a build the corresponding html directories. print "Checking HTML directories.\n" if $verbose; if (!-e $hroot) { mkdir($hroot,umask) || die("Cannot create directory $hroot\n"); chmod 0755, $hroot; } opendir(HDIR,$hroot) || die ("Cannot open directory $hroot\n"); closedir(HDIR); die("HTML directory $hroot is not writable\n") if !-w $hroot; print "HTML Directory $hroot is OK\n" if $verbose; foreach (@mdirs) { local($x) = $hroot."/".$hdir{$_}; if (!-e $x) { mkdir($x,umask) || die("Cannot create directory $x\n"); chmod(0755,$x); } opendir(HDIR,$x) || die ("Cannot open directory $x\n"); closedir(HDIR); die("HTML directory $x is not writable\n") if !-w $x; print "HTML Directory $x is OK\n" if $verbose; } ###################################################################### # # Write the master index file # ###################################################################### $indexfile = "$hroot/index.html"; print "Writing master $indexfile\n" if $verbose; open(HFILE,">$indexfile") || die("Cannot open index file $indexfile\n"); print HFILE "Octave Index\n"; print HFILE "\n"; print HFILE "

Octave Index

\n"; &tagline; # Print a short introduction # Print directory listing print HFILE "

Octave Directory Indices

\n
\n";
print HFILE "\n";

# Include links to every file that was found

print HFILE "

Identifiers found in these directories

\n"; # We'll do this five across in alphabetical order $i = 1; foreach (@names) { # $b = " " x (15 - length($_)); my ($j,$b) = padding($_) ; $html = "$hdir{$mdir{$mfile{$_}}}/$_.html"; print HFILE "$_$b"; print HFILE "\n" if int($i/5) < int(($i+$j)/5) ; $i+=$j; } print HFILE "
\n"; close(HFILE); ###################################################################### # # Write an index for each html subdirectory # ###################################################################### @readme = grep(/readme/i,@mfiles); foreach $dir (@mdirs) { $indexfile = "$hroot/$hdir{$dir}/index.html"; print "Writing an index file $indexfile\n" if $verbose; open(HFILE,">$indexfile") || die("Cannot open index file $indexfile\n"); print HFILE "Index for Directory $dir\n"; print HFILE "\n"; print HFILE "[Return to Master Index]\n"; print HFILE "

Index for $dir

\n"; &tagline; # Now look for a Readme.m file, seemingly a Octave standard. If there # is one, then the help portion is included in the index file. foreach $file (@readme) { next if !($mdir{$file} eq $dir); open(MFILE,$file) || die("Cannot open the file $file"); # Help Cross Reference information undef(@zref); foreach $_ (@mfiles) { push(@zref,$name{$_}) if $ref{$file,$_} == 2; } # Look for the octave help text block $headline = "Readme"; &writehelpblock; } # Now write the index catalog for the .m files in this directory print HFILE "

Octave files in this Directory

\n
\n";
  foreach $file (@mfiles) {
    next if $dir ne $mdir{$file};
    # $b = " " x (15 - length($name{$file}));
    my $b = padding($name{$file}) ;
    $html = $name{$file}.".html";
    print HFILE "$name{$file}$b$lookfor{$file}\n";
  }
  print HFILE "
\n"; print HFILE "
\n"; close(HFILE); } ###################################################################### # # Write an html file for every m-file # ###################################################################### # Now write the html file for each octave file. Need to reread each octave # file to find the help text. Note that we can't do this in a single loop # because we want the back reference information, and also some people # put the help text before the function declarations. # Need a list of mfiles with unique identifiers @umfiles = values(%mfile); foreach $file (@mfiles) { $h = "$hroot/$hdir{$mdir{$file}}/$name{$file}.html"; print "Writing $h\n" if $verbose; # Cross Reference information # Find list of names. undef(@xref); undef(@yref); undef(@zref); foreach (@umfiles) { next if ($name{$_} eq $name{$file}); push(@xref,$name{$_}) if $ref{$file,$_} == 1; # files we call push(@yref,$name{$_}) if $ref{$_,$file} == 1; # files that call us push(@zref,$name{$_}) if $ref{$file,$_} == 2; # files in the comment lines } open(MFILE,"<$file") || die("Cannot open $file"); open(HFILE,">$h") || die("Cannot open $h"); print HFILE "$hdir{$file}/$hfile{$file}\n"; print HFILE "\n"; print HFILE "[Index for $mdir{$file}]\n"; print HFILE "[Return to Master Index]\n"; print HFILE "

$name{$file}

\n"; print HFILE "

($mdir{$file}/$name{$file}.m)

\n"; # If this is a function, then write out the first line as a synposis if ($mtype{$file}) { print HFILE "

Function Synopsis

\n"; print HFILE "
$synopsis{$file}
\n"; } # Write the help block $headline = "Help text"; &writehelpblock; print HFILE "

Cross-Reference Information

" if (@xref || @yref); if (@xref) { print HFILE "This $mtype{$file} calls\n"; print HFILE "
    \n"; foreach $x (sort @xref) { $html = "../$hdir{$mdir{$mfile{$x}}}/$x.html"; # $b = " " x (15 - length("$x")); my $b = padding($name{$file}) ; print HFILE "
  • $x".$b."$mfile{$x}
  • \n"; } print HFILE "
\n"; } if (@yref) { print HFILE "This $mtype{$file} is called by\n"; print HFILE "
    \n"; foreach $y (sort @yref) { $html = "../$hdir{$mdir{$mfile{$y}}}/$y.html"; $b = " " x (15 - length("$y")); print HFILE "
  • $y".$b."$mfile{$y}
  • \n"; } print HFILE "
\n"; } # Include source text if requested if ($opt_i) { print HFILE "

Listing of $mtype{$file} $mfile{$file}

\n"; seek(MFILE,0,0); print HFILE "
\n";
    while () {
      &htmlchar;
      if (/^\s*$CR/) {
        foreach $z (@zref) {
          next if //;
          $html = "../$hdir{$mdir{$mfile{$z}}}/$z.html";
          s/(\W+)($z)(\W+)/$1$2<\/A>$3/gi;
        }
      } else {
        foreach $x (@xref) {
          next if //;
          $html = "../$hdir{$mdir{$mfile{$x}}}/$x.html";
          s/(\W+)($x)(\W+)/$1$2<\/A>$3/g;
          s/^(\s*)($x)(\W+)/$1$2<\/A>$3/g;
        }
      }
      print HFILE $_;
    }
    print HFILE "
\n"; } # Print a date stamp print HFILE "
\n"; &tagline; print HFILE ""; close(MFILE); close(HFILE); }