#!/usr/bin/perl

use Text::Wrap qw(wrap $columns);
# Uncomment next line if running on a macintosh
use Mac::StandardFile;


#number of columns for wrapping
$columns=58;

print "###################################################\n";
print "##### processing manual pages with matlabdoc ######\n";

#do the identification of the platform

# Default is Linux or Unix box
$sep = '/';			
$cur = '.';
$up = '..';


# if the platform is a mac
if ($^O eq "MacOS")
{
  $sep = ':';				
  $cur = '';
  $up = ':';
}

#if the platform is something from winhell
if ($^O eq "MSWin")
{
	$sep = "\\";			
 	$cur = '.';
 	$up = '..';
}

$inDir =$cur.$sep;
$outDir = $cur.$sep."doc".$sep;
$HTMLoutDir ="";
$LatexoutDir ="";

if ($^O ne "MacOS")
{
	# now parse the input
	while (($_=shift))
	{
	  SWITCH:
	  {
	    m/^(\-i)/	and  	$inDir = shift;
	    m/^(\-d)/	and  	$outDir = shift;
	    m/^(\-h)/	and  	$HTMLoutDir = shift;
	    m/^(\-l)/	and  	$LatexoutDir = shift;
	  }
	}
}
else
{
	# assume we are in the droplet
	&macObtainFiles;

	$#ARGV == 0 	or die "Please drop only one directory at a time";
	$inDir = shift;
	$inDir = $inDir.":";

	print "\nPlease enter the name of the output directory[$inDir"."doc:]\n";
	$outDir = <>;
	chomp($outDir);
	$outDir = "$inDir"."doc:" unless $outDir;
	
	$inDir =~ m/.+:(.+):/;
	
	$dirName = $1;
}


print "input directory: $inDir\n";
print "output directory: $outDir\n";

# here start to initialize the target directory
chdir $inDir;

if ($HTMLoutDir eq "")				  
{	
	-d $outDir 		or mkdir($outDir, 0777);
	$HTMLoutDir = $outDir."html".$sep;
}  #html output directory

if ($LatexoutDir eq "")
{
	-d $outDir 		or mkdir($outDir, 0777);
	$LatexoutDir= $outDir."latex".$sep;
}  #latex output directory


-d $HTMLoutDir 	or mkdir($HTMLoutDir,0777);
-d $LatexoutDir or mkdir($LatexoutDir,0777);


#launches the recursive routine

treatFolder($inDir,$dirName);


######################################################
#
#this routine searches iteratively in the directories and subdirectories
#for producing the documentation of the matlab classes found
#
######################################################

sub treatFolder
{
  #$folder - is the directory whish is currently evaluated
  #$section - is the name of the folder currently evaluated
  my ($folder,$section) = @_;
  
  #here define al the global variables used by the system
  #for processing the manual pages
  $current_dir_name = "";
  $constructor_name = "";
  $function_name = "";
  
  $latex_manual = "";
  $latex_manual_top_section ="";
  $latex_manual_synopsis_section = "";
  $latex_manual_description_section = "";
  $latex_manual_remarks_section = "";
  $latex_manual_examples_section = "";
  $latex_manual_other_section = "";
  $latex_manual_see_section = "";
  $latex_manual_methods_section = "";
  
  $latex_manual_constructor = "";
  $latex_manual_constructor_see_section = "";

  $html_manual = "";
  $html_manual_top_section ="";
  $html_manual_synopsis_section = "";
  $html_manual_description_section = "";
  $html_manual_remarks_section = "";
  $html_manual_examples_section = "";
  $html_manual_other_section = "";
  $html_manual_see_section = "";
  $html_manual_methods_section = "";
  
  $html_manual_constructor = "";
  $html_manual_constructor_see_section = "";
  
  $matlab_help = "";
  $matlab_help_methods_section = "";
  $matlab_help_constructor = "";
  $matlab_help_constructor_see_section = "";
    
    
  #reads the file in the current  directory and saves them in a variable
  opendir (FOLDER, $folder) or die "Error: directory $folder not available";
  my @files = readdir FOLDER;
  closedir FOLDER;
  $current_dir_name =$section;
  
  # look if the folder is part of an OO matlab strucrture
  # if it is true we extract it from the list of the files
  my $f=0;
  my $constr ="";
  
  #scan all the files in the list if it is a matlab class
  if ($section =~ /Class\s(.+)/i)
  {
    foreach $aFile (@files)
    {
      #look for the constructor of the class
      if ($aFile eq (lc($1).".m"))
      {
	$constr = $aFile;
        @files = @files[0 .. ($f-1) , ($f+1 .. $#files)];
      }
      $f++;
    }
  }
  
  # define all the variables needed to process the manual pages
  my @subFoldList = ();
  my @classNames = ();
    
  #if there is a constructor
  if($constr)
  {
    ($manual_page_source,$constructor_name)=load_manual_code($folder.$constr);
    $current_dir_name=$constructor_name;
    
    if ($manual_page_source eq "") 
    {die "No manual page found in constructor $constr\n";}
               
    # get anyting between two @
    while($manual_page_source=~ /@(.+?)(?=(@))/sg)
    {
      # print "$1 \n";
      process_segment($1,$constructor_name);
    }
    
    # get the last one
    $manual_page_source=~ /@.+@(.+)/s;
    # print "$1 \n";
    process_segment($1,$constructor_name);
    
    #build the first part of the manual for the constructor
    update_m_file($constructor_name,$folder.$constr);
    build_html_page($constructor_name);
    build_latex_page($constructor_name);
      
  } 
  

  #this is the matlab file parsing the code
  #all the other files are searched for processing manual pages
  foreach $aFile (@files)
  {
    $lFile = $folder.$aFile;
    
    #if it is a directory add it to the subdirectories and class list
    if (-d $lFile) 
    {
      @subFoldList = ( @subFoldList, $lFile.$sep);
      @classNames = ( @classNames, $aFile);
    }
    #when it is a possible matlab file with a manual page to process	
    elsif ($aFile =~/\.m$/)  #when it is a possible m file
    {
      ($manual_page_source,$function_name)=load_manual_code($folder.$aFile);
	
      if ($manual_page_source)
      { 
	#reset all the variables
        $html_manual_top_section ="";
	$html_manual_synopsis_section = "";
	$html_manual_description_section = "";
	$html_manual_remarks_section = "";
	$html_manual_examples_section = "";
	$html_manual_other_section = "";
	$html_manual_see_section = "";
	
	$latex_manual_top_section ="";
	$latex_manual_synopsis_section = "";
	$latex_manual_description_section = "";
	$latex_manual_remarks_section = "";
	$latex_manual_examples_section = "";
	$latex_manual_other_section = "";
	$latex_manual_see_section = "";
	
	$matlab_help = "";
	
	# get anyting between two @
	while($manual_page_source=~ /@(.+?)(?=(@))/sg)
	{
	  process_segment($1,$function_name);
        }    
	# get the last one
	$manual_page_source=~ /@.+@(.+)/s;
	process_segment($1,$function_name);

	update_m_file($function_name,$folder.$aFile);
	build_html_page($function_name);
	build_latex_page($function_name);
      }      
    } 
  }

  #process the page for the second time to add the last parts 
  #and save the results to disk
  if($html_manual_constructor)
  { 
    update_m_file($constructor_name,$folder.$constr);
    build_html_page($constructor_name);
    build_latex_page($constructor_name);
  }
  #othervise save the latex manual page
  elsif ($latex_manual)
  {
    save_latex_page($current_dir_name);
  }
  
  #explore the subdirectories
  my $n=0;
  foreach my $aSub (@subFoldList)
  {
	if (!($aSub =~ /private/i) and !($classNames[$n] =~ /\./))
	{
      #if it is a directory of a matlab class
	  if ($classNames[$n] =~ /^\@/)
      {
	    $class = substr $classNames[$n], 1;
	    #go into recursion
	    print "now entering  $classNames[$n]\n";
	    &treatFolder($aSub, "Class $class");
	  }
	  else
      {   
        #go in  in any case to see if there is  something
	    print "now entering  $classNames[$n]\n";
	    &treatFolder($aSub, $classNames[$n]);
	  }
	}
	$n++;
  }
     
}   
    
    
######
## this function takes the segments of code and puts in the appropriate 
## global variables all the segments of the code of the manual page. 
sub process_segment
{
  my ($segment_source,$f_name) = @_;  
  
  SWITCH: for ($segment_source) 
  {
    m/^purpose\s+(.+)/s && do
    {
       #get rid of the purpose tag from the current segment
       $_=$1;
       
       # inizialize the different sections
       $matlab_help = uc($f_name)." ";
              
       if (/([^\.]+)\.\s*(.*)/s)    #the first full stop is found
	   {
	     #brief description
	     $matlab_help = $matlab_help.$1."\n\n";	     
	     #additional description
	     if ($2) 
	     {$matlab_help=$matlab_help.$2."\n";}
	     
	     $html_manual_top_section = $html_manual_top_section."<p>\n$1<p>\n";	          
         if ($2)
         {$html_manual_remarks_section =$2."\n";}
         
         $latex_manual_top_section = $latex_manual_top_section."$1\n";	          
         if ($2)
         {$latex_manual_remarks_section =$2."\n";}
         
         #add the short description of the method
         if($constructor_name and !($constructor_name eq $f_name))
         {
           $matlab_help_methods_section=
              $matlab_help_methods_section."<dt> $f_name <dd>".$1."\n";            
           $html_manual_methods_section=$html_manual_methods_section.
           "<LI><A HREF=\"$f_name.html\">$function_name</A>\n".$1."\n";
           $latex_manual_methods_section=$latex_manual_methods_section.
              "\\item {\\tt ".$f_name."}   ".$1."\n";
         }         
                	     
	   } 
       elsif (m/(.+)\s*/s)  #no full stop on this section
	   {
	     $matlab_help = $matlab_help.$1."\n\n";
	     $html_manual_top_section = $html_manual_top_section."<p>\n$1<p>\n";
	     $latex_manual_top_section = $latex_manual_top_section."$1\n";
	     #add the short description of the method
         if($constructor_name and !($constructor_name eq $f_name))
         {
           $matlab_help_methods_section=
              $matlab_help_methods_section."<dt> $f_name <dd>".$1."\n";
           $html_manual_methods_section=$html_manual_methods_section.
           "<LI><A HREF=\"$f_name.html\">$function_name</A>\n".$1."\n";
           $latex_manual_methods_section=$latex_manual_methods_section.
              "\\item {\\tt ".$f_name."}   ".$1."\n";
         }
	     
	   }
    };
    /^synopsis\s+(.+)\n/s  && do 
	{
	  $matlab_help=$matlab_help.uc($1);
	  $html_manual_synopsis_section = $html_manual_synopsis_section."<pre>".$1."</pre>";
      $latex_manual_synopsis_section = $latex_manual_synopsis_section."{\\tt ".$1."}\\\\ \n";
	  $last_synopsis = $1;
	};
	/^description\s+(.+)/s && do
    {
      $matlab_help=$matlab_help." ".$1."\n";
      $html_manual_description_section = $html_manual_description_section."<code>$last_synopsis</code>\n$1<p>\n";
      my $latex_synopsis = $last_synopsis;
      $latex_synopsis =~ s/{/\\{/g;
	  $latex_synopsis =~ s/}/\\}/g;
	  if (!($latex_manual_description_section))
	  {
	    $latex_manual_description_section = $latex_manual_description_section.
        "{\\tt $latex_synopsis} \n$1";
	  }
	  else
	  {
        $latex_manual_description_section = $latex_manual_description_section.
        "\\vspace{4mm}\\\\ \n\\hspace{2mm}\n{\\tt $latex_synopsis} \n$1";
      }
    };
    /^examples\s+(.+)/s && do
    {
      $matlab_help=$matlab_help." ".$1."\n";
      $html_manual_examples_section = $html_manual_examples_section."$1<p>\n";
      $latex_manual_examples_section = $latex_manual_examples_section.$1."\n";
    };
    /^section\s+(.+)/s && do
    {
      #get rid of the section tag from the current segment
      $_=$1;
              
      if (/([^\.]+)\.\s*(.*)/s)    #the first full stop is found
	  {
	    #title of the section
	    $matlab_help = $matlab_help.ucfirst($1)."\n";	     
	    #text of the section
	    if ($2) 
	    {$matlab_help=$matlab_help."\n".$2."\n";}
	     
	    $html_manual_other_section = $html_manual_other_section."<p>
<font size=+2>".ucfirst($1)."</font></p>\n";         
        if ($2)
        {$html_manual_other_section =$html_manual_other_section.$2."<p>\n";}
        
        $latex_manual_other_section = $latex_manual_other_section."
\\begin{description}\n \\item[".ucfirst($1)."]\\ \\newline \\newline \n";	          
        if ($2)
        {$latex_manual_other_section =$latex_manual_other_section.
          $2."\\end{description}\n";}
      }
    };
	/^see\s+(.+)/s  && do
    {
      if(($constructor_name) and ($constructor_name eq $f_name))
      {
        $matlab_help_constructor_see_section="\n"."See also: ".uc($1)."\n";
      }
      else
      {
        $matlab_help=$matlab_help."\n"."See also: ".uc($1)."\n";
      }
      my @see_functions=split(/ /,$1); 
      foreach $see ( @see_functions)
	  {
		if($see=~ /(.+),/)
		{
		  $see=$1;
		  $html_manual_see_section=$html_manual_see_section."<a href=\"$see".".html\"><b>$see</b></a>, ";
        }
        else
        {
          $html_manual_see_section=$html_manual_see_section."<a href=\"$see".".html\"><b>$see</b></a>";
        }
	  }  
      $latex_manual_see_section=$latex_manual_see_section.$1."\n";
    };
  }  # end of the switch statement       
}


######
## this function loads the code of the manual page from the 
## m file and returns it with the the name of the m function
sub load_manual_code
{
  my ($IFile) = @_;
  my $f_name="";
  my $page_source="";

  print "analyzing file: $IFile\n";    

  open (AFILE, $IFile) or die "Error: cannot access file\n    $IFile";

  # get the first line of the opened file and read the function name
  $_ = <AFILE>;
  if (/^function/i)   #this is a matlab file (at least it looks like one)
  {
    # get the name of the matlab function
    /^function.*=\s*(\w+)\(/i;
    # and save the name of the function and the first line 
    $f_name = $1;
    if ( $f_name eq "")
    {
      /^function\s*(\w+)\(/i;
      $f_name = $1;
    }
    #messy but works
    if ( $f_name eq "")
    {
      /^function\s*(\w+)/i;
      $f_name = $1;
    }
  }
  else {return ($page_source,$f_name);}
    
  # read the input file and save the manual page
  while (<AFILE>)
  {
    if (/%MAN_PAGE_BEGIN/)  #yes there is a man page	
    {
      print "   processing man page\n";
	 
	  $_ = <AFILE>  or die "End of file reached and no MAN_PAGE_END found\n";  	
      while (!/%MAN_PAGE_END/)	
	  {                     
        $page_source=$page_source.$_;
        $_ = <AFILE>  or die "End of file reached and no MAN_PAGE_END found\n";
      }
    }
  }   
  close AFILE; 
  
  # now the source code of the manual is in the $page_source variable  
  # eliminate the leading matlab (%) comments and spaces 
  $page_source =~ s/<math>(.+?)<\/math>/preserve_math($1)/egiso;
  $page_source =~ s/^\%\s*([.\@]*)/$1/mg;
      
  return ($page_source,$f_name);  
}

sub preserve_math
{
  my ($math_segment) = @_;
  $math_segment =~ s/^%//emg;
  $math_segment ="<math>".$math_segment."</math>";
  $math_segment;
}

#############
## this function is used to build the html page for all the manual pages
sub build_html_page
{
  my ($f_name) = @_;
  my $html_page="";
  
  $html_page="
<html><head><title>$constructor_name (MATLAB Function Reference)</title>
<!-- $Revision: 1.7 $  $Date: 1997/12/24 23:01:29 $ -->
<!-- $Log: $f_name.html,v $
# online doc for 5.2 release
# -->
<!-- DOCNAME: MATLAB Function Reference -->
<script language=\"Javascript\">
function slipInNewDest(cname){ 
  if ((navigator.appName == 'Microsoft Internet Explorer') && (navigator.appVersion.substring(0,1) == '2' )) {window.location = cname.toLowerCase()+\".html\";}
  else {window.document.f2.action=cname.toLowerCase()+\".html\";}
}
</script>
</head>
<body bgcolor=#f0f0f0>
<table border=0 width=\"100%\" cellpadding=0 cellspacing=0><tr>
<td valign=baseline bgcolor=\"#9bd0e0\">&nbsp;<font size=+2>MATLAB Function Reference</font></td>
<td valign=baseline align=right bgcolor=\"#9bd0e0\"><form name=\"f2\" onSubmit=\"slipInNewDest(f2.cmdname.value)\">&nbsp;&nbsp;<b>Go to function:</b> <input name=\"cmdname\" type=\"text\" size=\"12\"></form></td>
<td valign=baseline align=right bgcolor=\"#9bd0e0\">&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"../../search1.html\" target=\"_top\">Search</a>&nbsp;&nbsp;&nbsp;&nbsp<a href=\"../../helpdesk.html\" target=\"_top\">Help Desk</a>&nbsp;</td>
</tr>
</table>

<table border=0 width=\"100%\" cellpadding=0 cellspacing=0>
  <tr>
    <td><font size=+4>$f_name</font> </td>
    <td valign=baseline align=right>&nbsp;&nbsp;&nbsp;";
  #if it is the constructor  
  if($f_name eq $constructor_name)
  {  
    $html_page=$html_page."
       <a href=\"#methods_sec\"><font size=+1>Methods</font></a>&nbsp;&nbsp;&nbsp;";
  }
  if($html_manual_examples_section)
  {  
    $html_page=$html_page."
       <a href=\"#exmpl_sec\"><font size=+1>Examples</font></a>&nbsp;&nbsp;&nbsp;";
   }
  if($html_manual_see_section)
  {
    $html_page=$html_page."
       <a href=\"#seeal_sec\"><font size=+1>See Also</font></a>";
  }
  $html_page=$html_page."       
    </td>
  </tr>
</table>


<!-- FNAME:$f_name -->
</p>".$html_manual_top_section."<p>";

  #usage and description part of the html page
  if($html_manual_synopsis_section)
  {
    $html_page=$html_page."
<font size=+2>Syntax</font></p>
<ul>".$html_manual_synopsis_section."</ul>
<p>
<font size=+2>Description</font></p>".$html_manual_description_section;
  }
  #remarks part of the html page
  if($html_manual_remarks_section)
  {
    $html_page=$html_page."<p>
<font size=+2>Remarks</font></p>\n".$html_manual_remarks_section;
  }
  #examples part of the html page
  if($html_manual_examples_section)
  {
    $html_page=$html_page."<p>
<a name=\"exmpl_sec\"></a>    
<font size=+2>Examples</font></p>\n".$html_manual_examples_section;
  }
  
    #other part of the latex page
  if($html_manual_other_section)
  {
    $html_page=$html_page.$html_manual_other_section;
  }
  
  #at this point if it is the page of the constructor which is 
  #processed for the first time save the values and exit the function
  if(($f_name eq $constructor_name) and !($html_manual_constructor))
  {
    $html_manual_constructor=$html_page;
    $html_manual_constructor_see_section= $html_manual_see_section;
    return;
  }
  
  # if it is the second time that we process the constructor
  # put the saved values in the current values
  if(($f_name eq $constructor_name) and ($html_manual_constructor))
  {
    $html_page=$html_manual_constructor;
    $html_manual_see_section=$html_manual_constructor_see_section;
    #add the part with the methods
    if($html_manual_methods_section)
    {
      $html_page=$html_page."<p>
<a name=\"methods_sec\"></a>    
<font size=+2>Methods</font></p>\n<UL>".$html_manual_methods_section."</UL>\n";
    }    
  } 
  
  #add the see section
  if($html_manual_see_section)
  {
    $html_page=$html_page."<p>
<a name=\"seeal_sec\"></a>
<font size=+2>See Also</font></p>\n".$html_manual_see_section;
  }
  $html_page=$html_page."<hr><br>

<center>[ <a href=\"../../helpdesk.html\" target=\"_top\">Help Desk</a> ]</center>

<br>
<!-- Copyright (c) 1998 by The MathWorks, Inc. -->
<!-- Last updated:  -->
</body>
</html>";

  #substitute or eliminate all the latex and maths segments
  $html_page =~ s/<latex_section>(.+?)<\/latex_section>/process_latex($1,"html")/egiso;
  $html_page =~ s/<html_section>(.+)<\/html_section>/process_html($1,"html")/egiso;
  $html_page =~ s/<text_section>(.+)<\/text_section>/process_text($1,"html")/egiso;
  
  $html_page =~ s/<inline_math>(.+?)<\/inline_math>/process_inline_math($1,"html")/egiso;
  $html_page =~ s/<math>(.+?)<\/math>/process_math($1,"html")/egiso;
  #redefined the <dl> tags.
  $html_page =~ s/<dl>(.+?)<\/dl>\s*\n/process_list("<dl>".$1."<\/dl>\n","html")/iegsxo;

  -d $HTMLoutDir.$current_dir_name.$sep or mkdir($HTMLoutDir.$current_dir_name,0777);
  
  open (AFILE, ">$HTMLoutDir".$current_dir_name.$sep."$f_name.html") or die "Error: cannot create file\n   $HTMLoutDir".$current_dir_name.$sep."$f_name.html"; 
  print AFILE $html_page;
  close AFILE;
}  
  

########
# function for updating the matlab files and adding the help page processed
##

sub update_m_file
{
  my ($f_name,$file) = @_;
  my $help_page="";
  
  $help_page=$matlab_help;
  #the first time it is called for the constructor
  if(($f_name eq $constructor_name) and !($matlab_help_constructor))
  {  
    $matlab_help_constructor=$help_page;
    return;
  }  
  
  #the second time it is called with the constructor
  if(($f_name eq $constructor_name) and ($matlab_help_constructor))
  {  
    $help_page=$matlab_help_constructor;
    $help_page=$help_page."The class defines the following methods:\n\n".    
        "<dl>\n".
        $matlab_help_methods_section."</dl>\n".
        $matlab_help_constructor_see_section;
  }

  #process the help file
  $help_page =~ s/<code>([\w_\s*]+)<\/code>/uc($1)/eigm;
  #sobstitute or eliminate all the latex and maths segments
  $help_page =~ s/<latex_section>(.+?)<\/latex_section>/process_latex($1,"help_file")/egiso;
  $help_page =~ s/<html_section>(.+)<\/html_section>/process_html($1,"help_file")/egiso;
  $help_page =~ s/<text_section>(.+)<\/text_section>/process_text($1,"help_file")/egiso;
  
  $help_page =~ s/<inline_math>(.+?)<\/inline_math>/process_inline_math($1,"help_file")/egiso;
  
  #do the formatting of the manual page 
  $help_page =~ s/<dl>/"\n<dl>"/egm;
  $help_page =~ s/<\/dl>/"<\/dl>\n"/egm;
  $help_page =~ s/<math>/"\n<math>"/egm;
  $help_page =~ s/<\/math>/"<\/math>\n"/egm;
    
  $help_page = wrapper("","","\n\n",$help_page);

  $help_page =~ s/<math>(.+?)<\/math>/process_math($1,"help_file")/egiso;
  
  $help_page =~ s/<dl.*?>(.+?)<\/dl>\s*\n/process_list("<dl>".$1."<\/dl>\n","help_file")/iegsxo;

  #add the comments at the begin of each line

  $help_page ="%".$help_page; #add the comment to the first line
  $help_page =~ s/\n/ "\n"."%    "/eg;
  
  #reopen the file to put the help page
  open (AFILE, $file) or die "Error: cannot access file $file";

  #get the first line of the opened file
   
  $_ = <AFILE>;

  $new_file = $_;

  #add the help page
  $new_file= $new_file.$help_page."\n\n";

  #skip the old help page
  while (($_=<AFILE>)&& (!/%MAN_PAGE_BEGIN/)) {}

  #add the rest of the file
  $new_file = $new_file.$_;

  while (<AFILE>)
  {
  	$new_file = $new_file.$_;
  } 

  close AFILE;
  
  #copy on top of the old file
  open (AFILE, ">$file") or die "Error: cannot access file $file"; 
  print AFILE $new_file;
  close AFILE;
}   

########
## this function does the wrapping of the lines to give a nicer apparence
sub wrapper
{
  my ($first_separator,$second_separator,$paragraph_terminator,$help_page) =@_;
  
  $help_page=~s/<br>/"<br>\n\n"/egm;
  
  @paragraphs = split (/\n+\n/s,$help_page);
  
  my $tmp_help_page="";
  foreach $sentence (@paragraphs)
  {
    if (!($sentence=~/^</))
    {
      $sentence=~ s/\n/" "/egm;
      $sentence=wrap($first_separator,$second_separator,$sentence);
    }
    $tmp_help_page=$tmp_help_page.$sentence.$paragraph_terminator;
  }
  $tmp_help_page=~s/<br>\n\n/"\n"/egm;
  
  $tmp_help_page;
}


#############
## this function is used to build the latex page for all the manual pages
sub build_latex_page
{
  my ($f_name) = @_;
  my $current_latex_page="";
  
  #this is used for just saving the latex page of manual 
  #of functions which are not method of a class
  if(($f_name eq ""))
  {}
  
  
  $current_latex_page="\\newpage \\noindent ".
     "{\\bf \\huge $f_name}\\\\  \\rule[3pt]{\\textwidth}{1pt}\\\\\n";
     "\n\\begin{description}\n ";
  
  $current_latex_page=$current_latex_page.
  "\\begin{description}\n \\item[Purpose]\\ \\newline \\newline \n".
  $latex_manual_top_section."\\end{description}\n";  
  
  #usage and description part of the html page
  if($latex_manual_synopsis_section)
  {
    $current_latex_page=$current_latex_page."
\\begin{description}\n \\item[Synopsis]\\ \\newline \\newline \n".
$latex_manual_synopsis_section."\\end{description}\n"."
\\begin{description}\n \\item[Description]\\ \\newline \\newline \n".
$latex_manual_description_section."\\end{description}\n";
  }
  #remarks part of the latex page
  if($latex_manual_remarks_section)
  {
    $current_latex_page=$current_latex_page."
\\begin{description}\n \\item[Remarks]\\ \\newline \\newline \n".
$latex_manual_remarks_section."\\end{description}\n";
  }
  #examples part of the latex page
  if($latex_manual_examples_section)
  {
    $current_latex_page=$current_latex_page."
\\begin{description}\n \\item[Examples]\\ \\newline \\newline \n".
$latex_manual_examples_section."\\end{description}\n";
  }
  
  #other part of the latex page
  if($latex_manual_other_section)
  {
    $current_latex_page=$current_latex_page.$latex_manual_other_section;
  }
  
  #at this point if it is the page of the constructor which is 
  #processed for the first time save the values and exit the function
  if(($f_name eq $constructor_name) and !($latex_manual_constructor))
  {
    $latex_manual_constructor=$current_latex_page;
    $latex_manual_constructor_see_section= $latex_manual_see_section;
    return;
  }
  
  # if it is the second time that we process the constructor
  # put the saved values in the current values
  if(($f_name eq $constructor_name) and ($latex_manual_constructor))
  {
    $current_latex_page=$latex_manual_constructor;
    $latex_manual_see_section=$latex_manual_constructor_see_section;
    #add the part with the methods
    if($latex_manual_methods_section)
    {
      $current_latex_page=$current_latex_page."
\\begin{description}\n \\item[Methods]\\ \\\\ \n".
"\\begin{itemize}\n".
$latex_manual_methods_section."\\end{itemize}\n\\end{description}\n";
    }    
  } 
  
  #add the see section
  if($latex_manual_see_section)
  {
    $current_latex_page=$current_latex_page."
\\begin{description}\n \\item[See also]\\ \\newline \\newline \n".
    $latex_manual_see_section."\\end{description}\n";
  }

  if(($f_name ne $constructor_name))
  {
    $latex_manual=$latex_manual.$current_latex_page;
    return;
  }
  
  $latex_manual=$current_latex_page.$latex_manual;
 
  save_latex_page($constructor_name);
}
 
sub save_latex_page
{  
  my ($f_name)=@_;
  #now process the latex page
  
  $latex_manual =~ s/<code>([\w_\s*]+)<\/code>/"{\\tt $1}"/eigm;  
  
  $latex_manual =~ s/<latex_section>(.+)<\/latex_section>/process_latex($1,"latex")/egiso;
  $latex_manual =~ s/<html_section>(.+)<\/html_section>/process_html($1,"latex")/egiso;
  $latex_manual =~ s/<text_section>(.+)<\/text_section>/process_text($1,"latex")/egiso;
  $latex_manual =~ s/<math>(.+?)<\/math>/process_math($1,"latex")/egiso; 
  $latex_manual =~ s/<inline_math>(.+?)<\/inline_math>/process_inline_math($1,"latex")/egiso;
  
  $latex_manual =~s/_/\\_/g;
  $latex_manual =~s/UnLiKeLyWrItTeN/_/g;
  $latex_manual =~ s/<dl>(.+?)<\/dl>\s*\n/process_list("<dl>".$1."<\/dl>\n","latex")/iegsxo; 
  $latex_manual=~s/<br>/"\\\\"/egm;
  
  print "Saving... $f_name.tex\n";
  
  open (AFILE, ">$LatexoutDir"."$f_name.tex") or die "Error: cannot create file\n   $LatexoutDir"."$f_name.tex"; 
  print AFILE $latex_manual;
  close AFILE;
}


####################
### this function is used for processing the lists 
###(it does not work with nested lists for the text part)
sub process_list
{
  my ($help_page,$part)=@_;
  
  if ($part eq "help_file")
  {
    $columns=56;  # change the number of the wrapping columns
  
    $help_page =~ s/<dt>\s*(.+?)\s*<dd>\s*(.+?)\s*(?=(<dt>))/wrapper("  ", "      ","\n",uc($1).": ".$2)/iegsxo;
    #this is for the last line of the list
    $help_page =~ s/<dt>\s*(.+?)\s*<dd>\s*(.+?)\s*(?=(<\/dl>))/wrapper("  ", "      ","\n",uc($1).": ".$2)/iegsxo;  
  
    $help_page =~ s/<dl>\s*\n//egm;
    $help_page =~ s/<\/dl>\s*\n/"\n"/egm;
  
    # reset the the number of the wrapping columns tp the original value
    $columns=58;
    
    $help_page;  
  }
  elsif ($part eq "html")
  {

    $help_page =~ s/<dt>\s*(.+?)\s*<dd>\s*(.+?)\s*(?=(<dt>))/"<LI><code>$1<\/code> ".$2."\n"/iegsxom;
    $help_page =~ s/<dt>\s*(.+?)\s*<dd>\s*(.+?)\s*(?=(<\/dl>))/"<LI><code>$1<\/code> ".$2."\n"/iegsxom; 

    $help_page =~ s/<dl>\s*\n/"<ul>\n"/egm;
    $help_page =~ s/<\/dl>\s*\n/"<\/ul>\n"/egm;
    
    $help_page; 

  }
  elsif ($part eq "latex")
  {
  	$help_page =~ s/<dt>\s*(.+?)\s*<dd>\s*(.+?)\s*(?=(<dt>))/"{\\tt $1}: & $2 \\\\ \n"/iegsxom;
	#this is for the last line of the list
	$help_page =~ s/<dt>\s*(.+?)\s*<dd>\s*(.+?)\s*(?=(<\/dl>))/"{\\tt $1}: & $2 \\\\ \n"/iegsxom;

	$help_page =~ s/<dl>/ "\\\\  \n\\begin{tabular}{lp{12cm}}"/eigm;
	$help_page =~ s/<\/dl>/ "\\end{tabular} \\\\ \n"/eigm;
	
	$help_page;
  }
  else {die "not a valid type of file to process in function: process_list";}    
}


#############
## process the bits of the code between <latex_section> </latex_section> bits
sub process_latex
{
  my ($help_page,$part)=@_;
  
  if ($part eq "help_file")
  {
    $help_page="";
  }
   elsif ($part eq "html")
  {
    $help_page="";
  }
  elsif ($part eq "latex")
  {
    $help_page =~s/_/UnLiKeLyWrItTeN/g;
  }
  else {die "not a valid type of file to process in function: process_latex";}
}

#############
## process the bits of the code between <html_section> </html_section> bits
sub process_html
{
  my ($help_page,$part)=@_;
  
  if ($part eq "help_file")
  {
    $help_page="";
  }
   elsif ($part eq "html")
  {
    $help_page="<br>".$help_page."<br>\n";
  }
  elsif ($part eq "latex")
  {
    $help_page="";
  }
  else {die "not a valid type of file to process in function: process_latex";}
}

#############
## process the bits of the code between <text_section> </text_section> bits
sub process_text
{
  my ($help_page,$part)=@_;
  
  if ($part eq "help_file")
  {
    $help_page;
  }
   elsif ($part eq "html")
  {
    $help_page="";
  }
  elsif ($part eq "latex")
  {
    $help_page="";
  }
  else {die "not a valid type of file to process in function: process_latex";}
}

#############
## process the bits of the code between <math> </math> bits
sub process_math
{
  my ($help_page,$part)=@_;
  
  if ($part eq "help_file")
  {
    $help_page =~ s/(.+)<alt>(.+)/$2/gs or $help_page =~ s/(.+?)//gs;
    $help_page;
  }
  elsif ($part eq "html")
  {
    $help_page =~ s/(.+)<alt>(.+)/<br><pre>$2<\/pre><br>\n/gs or 
        $help_page =~ s/(.+)//gs;
    $help_page;
  }
    elsif ($part eq "latex")
  {
    $help_page =~ s/(.+)<alt>(.+)/\\begin{equation}\n $1 \n\\end{equation}\n/gs or
    	$help_page =~ s/(.+)/\\begin{equation}\n $1 \n\\end{equation}\n/gs;
    $help_page =~s/_/UnLiKeLyWrItTeN/g;
    $help_page;
  }
  else {die "not a valid type of file to process in function: process_math";}
}    

#############
## process the bits of the code between <math> </math> bits
sub process_inline_math
{
  my ($help_page,$part)=@_;
  
  if ($part eq "help_file")
  {
    $help_page =~ s/(.+)<alt>(.+)/$2/gs or $help_page =~ s/(.+)//gs;
    $help_page;
  }
  elsif ($part eq "html")
  {
    $help_page =~ s/(.+)<alt>(.+)/<code>$2<\/code>/gs or $help_page =~ s/(.+)//gs;
    $help_page;
  }
    elsif ($part eq "latex")
  {
    $help_page =~ s/(.+)<alt>(.+)/\$$1\$/gs or $help_page =~ s/(.+)/\$$1\$/gs;
    $help_page =~s/_/UnLiKeLyWrItTeN/g;
    $help_page;
  }
  else {die "not a valid type of file to process in function: process_inline_math";}
}

#############
## For macintosh droplet
sub macObtainFiles
{ #Snaked from Chris Nandor's code on the MacPerl list. See www.MacPerl.com for
  #info on joining that list or checking out the archive.
  #This code will populate the @ARGV array, in case you didn't drop anything
  #your MacPerl droplet, but you want to work with a bunch of files anyway.
  # Note: don't forget... "use Mac::StandardFile;"


  if (!@ARGV) {
    my $sf_done;
    while (!$sf_done) {
      my $reply = StandardGetFile(0, '') or die $^E;
      die $^E if !$reply->sfGood;
      push @ARGV, $reply->sfFile;
      $sf_done++ unless
        MacPerl::Answer('Select another file?', qw(Yes No));
    }
  }
}



__END__

=head1 NAME

matlabdoc - a documentation generator for matlab functions

=head1 DESCRIPTION

Matlab doc is a perl script which reads the appropriate section
of code embedded in a matlab function and generates the documentation 
associated to the function. At the present matlabdoc generates the 
inline matlab, HTML and Latex documentation of the function.

The documentation is produced thanks o a series of commands that are 
recognised by the matlabdoc function. These are a mix of HTML tags and 
commands for defining the sections of the document.

The main idea of this system is that it is much easier to maintain
the documentation when it is embedded in the m file itself than
maintaining a lot of different version of the same document. 
In this way, every time a change is made, the programmer needs to update 
only the documentation source file; The changes will be propagated to
all the version fo the documentation  next time the matlab doc 
comman is run.

Matlabdoc has being designed to create the documentation for matlab 
classes and methods, but it can be also used for producing the 
documentation of functions. 

=head1 EMBEDDING MATLABDOC DOCUMENTATION IN M FILES

In order to embed the documentation in a matlab file (m file) it is necessary to 
defines two tags which identify the start and the end of the 
documentation paragraphs. These tags are

  %MAN_PAGE_BEGIN - for identifying the start of the section
  
  %MAN_PAGE_END   - for identifying the end of the section

Since the documentation is embedded in a matlab function  it is necessary to 
start all the lines of the documentation with the simbol % (which labels a 
comment line in matlab), so matlab will ignore all these lines.

The documentation inside these tags is organized in paragraphs. Each paragraph 
starts with a @ followed by an identifier. At present the following
identifiers are recognized by the system:

	@purpose
	@synopsis
	@description
	@examples
	@section
	@see
	
The @purpose directive introduces the section which describes the aim of the 
function and gives other related information. This is the first directive
that should be included in all documentation sections. matlabdoc takes everything 
until the first full stop (".") and uses it as brief description of the function
(the one that is searched by the find command in matlab). The rest follows in a
separate paragraph.

The @synopsis directive states that what follows is the syntax of the function.
If the function has more than one possible calling convetion it is necessary to
define each possible syntax using a @synopsis directive for each alternative.
Each @synopsis directive must be followed by a @description one.

A @description directive always follows each @synopsis directive,
and provides the description of the calling conventions
and the usage of the function whose syntax has been given in the preceeding 
@synopsis directive.

The @examples directive is the directive where exaples of use of the function  are
given. Usually there is at most only and @examples directive in each manual page. 

The @section directive is a general tag for creating first level headings in the
documentation. matlabdoc interprets everything until the first full stop (".") as 
the title of the section. These sections are appended at the end of the
documentation.

The @see directive is used to list the other related functions. It is a simple 
list of functions names separated by commas.

Within these directives paragraphs are separated by a empty line.

=head1 IMPROVING THE MANUAL PAGE LAYOUTS

In addition to the directives described above, a series of additional 
tags which resemble HTML commands are defined in order to improve the layout, 
and therefore the quality of the documentation. The following tags are 
recognized by matlabdoc:

	<text_section>  </text_section>
	<html_section>  </html_section>
	<latex_section>  </latex_section>
	
	<math> </math>
	<inline_math>  </inline_math>
	
	<dl>  <dt>  <dd>  </dl>
	<code>  </code>
	<br>

The first tree pairs of tags are not interpreted by the matlabdoc, but the text
included between them is directly copied to the relevant part of the documentation,
while it is excluded from the other ones. An example to how to use this follows:

  <html_section>

  <br>Figure 1.<IMG SRC="figure1.gif"><br>

  </html_section>

  <text_section>
		
  ---------------
  |  foo        |
  |        bar  |
  ---------------
		
  ^^^^ Figure 1. ^^^^
		
  </text_section>

The first section of text included between the <html_section> and </html_section>
tags will be included in the HTML documentation, the second between <text_section>
and </text_section>, will be embedded only in the online matlab documentation, while
nothing will appear in the Latex document.

The <math>, </math>, <inline_math> and </inline_math> tags are used to
embed maths in the documents. The formulas are defined using latex. The
<math> and </math> tags tell to the system to place the formula
separated from the text on a new line, while the other two tags are used
to embed formulas in the text. Since a lot of formulas cannot be
rendered in text mode both the tags admit an alternative syntax, 

  <math> latex_formula <alt> text_formula </math>
  <inline_math> latex_formula <alt> latex_formula </inline_math>
	
where the alternative representation of the formula is embedded in the text and 
HTML documents. If no alternative is provided and no rendering for the 
HTML is possible, no formula will appear in the text and HTML documentation.

The <dl>, <dt>, <dd>, and </dl> tags are used to specify description lists as in HTML. 
A list starts with the tag <dl>, and ends with the tag </dl>. The tag <dt> defines the
term described, while <dd> introduces its description. No nested list are supported.
An example of a list follows:

  <dl>
  <dt> x <dd> the value of the x axis
  <dt> y <dd> the value of the y axis
  <dt> z <dd> the value of the z axis
  </dl>
	
this will render in text as:

  X the value of the x axis
  Y the value of the y axis
  Z the value of the z axis
	
Comparable rendering are obtained in the other documentation.

The <code> and </code> tags are used to delimit a section of code. In the 
case of the matlab manual all the text included between these two tags is
converted in uppercase. In the case of HTML the <code> tags are maintained,
while in latex it is placed in a "{\tt }" section. Usually it is used to 
define the variables used by the function.

The <br> tag is used to force a new line in the documentation. It is possible to 
split a long text in paragraphs by separating them with an empty line.

=head1 AN EXAMPLE

After describing all the features of the matlabdoc a simple example of a 
matlab manual page written for matlabdoc.


  function a=foo(varargin)

  %MAN_PAGE_BEGIN
  %
  %   @purpose	this is the short description of 
  %   the function. Here I can add an optional longer 
  %   description of the function which will provide 
  %   more information to the user.
  %
  %   @synopsis	a=foo(x)
  %   @description  take the input value <code>x</code>
  %   to generate the output <code>a</code>
  %
  %   @synopsis	a=foo(x,y)
  %   @description  take the input values <code>x</code>
  %   and <code>y</code> to generate the output 
  %   <code>a</code>
  %
  %   @see function1, function2 
  %
  %MAN_PAGE_END

this will render in the online matlab help as:

  function a=foo(varargin)
  %FOO this is the short description of the function
  %   Here I can add an optional longer 
  %   description of the function which will provide 
  %   more information to the user.
  %
  %   A=FOO(X) take the input value X
  %   to generate the output A
  %
  %   A=FOO(X,Y) take the input values X
  %   and Y to generate the output A
  %
  %   See also: function1, function2 
  
  %MAN_PAGE_BEGIN
  %
  %   @purpose	this is the short description of
   
  .... rest of the manual page ....
     
  %
  %MAN_PAGE_END
  
similar results are produced for the HTML and latex section of the 
documentation. In this way the text of the documentation is always 
included in the m file and it cannot get lost.

=head1 THE PRODUCED DOCUMENTATION

As mentioned before the matlabdoc program has been designed to 
produce the documentation of a large OO matlab toolbox, and 
therefore the way in which it works serves at the best it original
purpose.

When matlabdoc is run from the command line it scans all the m files
in the current directory looking for embedded documentation and processing it. 
When it recursively repeats this for all the subdirectories. At present it does
not search for these files in the "private" directories of the matlab 
classes which contain the private methods of the class.

The processed text of the manual is added at the beginning of each 
matlab function after the first line. Any old documentation not  defined
between the %MAN_PAGE_BEGIN and  %MAN_PAGE_END is lost in the process.
In the case of a constructor of a class all the methods of the class 
are reported at the end of the function. 

In the case of the HTML documentation it is saved in the directory 

  doc/html/name_of_the_processed_directory
  
which is created if does not already exists. Each processed file generates 
a html file which bears the name "function.html". The possibility of using 
the search tool is granted only if the files are then moved in the directory
where all the HTML matlab documentation is placed.

In the case of the latex documentation it is saved in the directory

  doc/latex
  
which is created if does not already exists. All the files embedding documentation
found in each directory are saved in the file "name_of_the_processed_directory.tex".
The latex files do not include preamble and document specifications. In
this way they can be easily included in a larger latex document.

=head1 AUTHORS

Edy Bertolissi and Antoine Duchateau

=head1 AKNOLEDMENTS

This program has being developed within the FAMIMO project 
(ESPRIT project  I do not remember now, but I will come back 
to you) at the IRIDIA labs, Free University of Bruxelles (ULB), 
Belgium.

Please send comments and bugs reports to:

   eberto@iridia.ulb.ac.be


