#!/usr/local/bin/perl 

# java2html is a perl script to turn your java code into html documentation.
# 
# usage: java2html *.java
# 
# There are no command line options at this point. For each .java file in the
# command line a corresponding .html file will be written. In addition 
# .markup1 and .markup2 files will also be written for each java file. 
# 
# A state file is also written that contains variable, method and class
# information.
# 
# Written by Eric Soroos, soroos@u.washington.edu
# 
# Version 0.11a, 8-2-96
# Fixed:
#       Importing links
#       Implements and extends for class and interface headers that extended over
#                more than one line.
#       Understands this.variable and this.method
#       Understands method calls that are not part of object.method();
#       Marked up more variables.
#       
# Still to go:
#       Variable.classVariable.anything does not mark up the anything.
#       single letter variable names don't register when they are used alone in a superclass
#       Static Method calls and Static variable calls don't seem to work. 
#       Overloaded functions may or may not be linked right. 
#       
#       Loading of the previous state so that we don't have to re process all the files.
#       Intelligent file/directory management.
#       &quot; sometimes marks up quot as a method variable.
#       Knowlege of the java.* classes.
#        
# version 0.1a, 8-1-96
# First release. There are known cases where the code does not mark up correctly. 
# There are no known bugs that cause loss of data. if you find any, I'm all ears.
# 
# Additional modifications:
#   15-SEP-1998  txe  Output file for x.java is not x.java.html, not x.html
#

$debug1 = 0;    # checkIfVariableUse
$debug2 = 0;    # find variable use
$debug3 = 0;    # find Variable Declaration
$debug4 = 0;    # variable use markup
$debug5 = 0;    #constructor call
$debug6 = 0;    #interface...
$debug7 = 0;    #local method calls.
$debug8 = 0;    # this,super,static;
$debug9 = 0;    # this,super,static;
$debug10 = 0;   # implements

$printVariables = 0;

$lowMemOperation = 1 ;


$nothing = "";
$openClass = '<CLASS>';
$closeClass = '</CLASS>';
$openClassName = '<CLASSNAME>';
$closeClassName = '</CLASSNAME>';
$openMethod = '<METHOD>';
$closeMethod = '</METHOD>';
$openMethodName = '<METHODNAME>';
$closeMethodName = '</METHODNAME>';
$openMethodArguments = '<METHODARGS>';
$closeMethodArguments = '</METHODARGS>';
$openComment = '<COMMENT>';
$closeComment = '</COMMENT>';
$openVariableType = '<VARTYPE>';
$closeVariableType = '</VARTYPE>';
$openVariableName = '<VARIABLE>';
$closeVariableName = '</VARIABLE>';
$openConstructorCall = '<CONSTRUCTORCALL>';
$closeConstructorCall = '</CONSTRUCTORCALL>';
$openMethodType = '<METHODTYPE>';
$closeMethodType = '</METHODTYPE>';
$openExtends = '<EXTENDS>';
$closeExtends = '</EXTENDS>';
$openImplements = '<IMPLEMENTS>';
$closeImplements = '</IMPLEMENTS>';
$openClassVariable = '<CLASSVARIABLE>';
$closeClassVariable = '</CLASSVARIABLE>';
$openMethodVariable = '<METHODVARIABLE>';
$closeMethodVariable = '</METHODVARIABLE>';
$openMethodCall = '<METHODCALL>';
$closeMethodCall = '</METHODCALL>';
$openKeyword = '<KEYWORD>';
$closeKeyword = '</KEYWORD>';
$openSomethingElse = '<SOMETHING>';
$closeSomethingElse = '</SOMETHING>';
$openUnknownCall = '<UNKNOWNCALL>';
$closeUnknownCall = '</UNKNOWNCALL>';
$dummy = '<DUMMY>';
$openImports = '<IMPORTS>';
$closeImports = '</IMPORTS>';


$openCommentMarkup = "<FONT COLOR=\"FF0000\">";
$closeCommentMarkup = "</FONT>";
$openKeywordMarkup = "<FONT COLOR=\"008000\">";
$closeKeywordMarkup = "</FONT>";

$keyWords = $fieldModifiers;
@keyWords = ( 'abstract', 'break',  'byvalue', 'case', 'catch',  'class', 'const', 'continue',
        'default', 'do',  'else', 'extends', 'false', 'final', 'finally',  'for', 'goto', 'if',
        'implements', 'import', 'instanceof',  'interface', 'long', 'native', 'new', 'null', 'package',
        'private', 'protected', 'public', 'return',  'static', 'super', 'switch', 'synchronized', 'this',
        'threadsafe', 'throw', 'transient', 'true', 'try', 'void', 'while');

@primitiveTypes = ('float','double','int','byte','char','boolean','void');

$c = '\/\*';  # open comment Char
$cc = '\*\/'; # close comment char

$fieldModifiers = "public|private|protected|static|final|transient|volatile";

$delimeter = '<del>';

foreach $word (@keyWords) {
        $keyWords{$word} = "$openKeyword$word$closeKeyword";
}

foreach $word (@primitiveTypes) {
        $primitiveTypes{$word} = "$openKeyword$word$closeKeyword";
}

# foreach $word (@keyWords) {
#       print "$keyWords{$word}\n"; 
# }

if (!$ARGV[0]) {
#       die "no files selected\n";
        $ARGV[0] = "ThreeD.java";
}

$methodName = "";
$className = "";
%variableType = ();

foreach $file (@ARGV){
        open(JAVA,$file) || die "Couldn't open file $file\n";
                print "parsing file  : $file \n";
                &parseFile;
        close (JAVA);

        if (!($lowMemOperation)) {
                $allTheFilesContents{$file} = join ($delimeter,@theFile);
        }
        
        $htmlSaveFile{$file} = &htmlFileNamer($file); 

        $markupSaveFile{$file} = $htmlSaveFile{$file};
        $markupSaveFile{$file} =~ s/\.html$/.markup1/;
        &writeTheFile ($markupSaveFile{$file});

        $htmlLinkFile{$file} = &htmlSaveToLinkFile($htmlSaveFile{$file}); 

        @theFile = ();
}

if      ($lowMemOperation) {
        foreach $file (keys %markupSaveFile) {
                $markupSaveFile{$file} =~ s/^\>/\</;
                open (MARKUP,$markupSaveFile{$file}) || die " Couldn't open $markupSaveFile{$file}\n";
                        @theFile = <MARKUP>;  # yes, this is one big slurp. 
                close MARKUP;
                
                &parseMethods;
                $markupSaveFile{$file} =~ s/^\</\>/;
                $markupSaveFile{$file} =~ s/markup1$/markup2/;
                &writeTheFile ($markupSaveFile{$file});
        
                &markupFile;
        }
} else {
        foreach $file (keys %allTheFilesContents) {
#               print "file name : $file \n";
                @theFile = split(/$delimeter/o, $allTheFilesContents{$file});
                $allTheFilesContents{$file} = "";
                &parseMethods;
        
                $markupSaveFile{$file} =~ s/markup1$/markup2/;
                &writeTheFile ($markupSaveFile{$file});
        
                &markupFile;
        }       
}
&writeState;

sub htmlFileNamer { # Names the html file according to the name of the java file. Uses the full path.
        local($fileName) = @_;
        $fileName =~ s/^/>/;
# 16-SEP-1998 txe #
        $fileName =~ s/\.java/\.java\.html/ || die "Got something that doesn't look like a java file\n";
###################
        return $fileName;
}

sub htmlSaveToLinkFile { #returns the proper name for the link file given the mane of the save file;
        local($fileName,$workingDirectory) = @_;
#       $fileName =~ s/$workingDirectory[:\\\/](.+)$/$1/;
        $fileName =~ s/^.*:(\w+\.html)$/$1/;
        $fileName =~ s/^\>//;
        return $fileName; 
}
sub writeTheFile { # Writes out the contents of @theFile to disk using the name passed to the function.
        local($fileName) = @_;
        # uses global @theFile;
        open (MARKUP, $fileName) || die "couldn't open $fileName\n";
        print MARKUP "@theFile";
        close MARKUP;
}
        
sub writeState {
        open (STATE, ">java2html.state" ) || die " Couldn't open State File\n";
        print STATE "Files covered:\n";
        foreach $key (sort (keys %markupSaveFile)){
                print STATE "$key;$markupSaveFile{$key}\n";
        } 
        print STATE "\nmethods\n";
        foreach $method (sort keys(%methodData)) {
                print STATE "$method;$methodData{$method}\n";
        }
        print STATE "\n";
        
        print STATE "extendsWeb\n";
        foreach $key (sort keys(%extendsWeb)) {
                print STATE "$key;$extendsWeb{$key}\n";
        }
        print STATE "\n";
        
        print STATE "ClassData\n";
        foreach $class (sort keys(%classData)) {
                print STATE "$class;$classData{$class}\n";
        }
        print STATE "\n";
        
        print STATE "Link info \n";
        foreach $key (sort keys(%htmlLinkFile)) {
                print STATE  "$key;$htmlLinkFile{$key}\n";
        }
        print STATE "\n";
        
        print STATE  "Save info \n";
        foreach $key (sort keys(%htmlSaveFile)) {
                print STATE "$key;$htmlSaveFile{$key}\n";
        }
        print STATE "\n";
        print STATE "variables:\n";
        foreach $variable (sort keys(%variableType)) {
                print  STATE "$variable;$variableType{$variable} \n";
        }
        print STATE "\n";

        close STATE;
}
sub anchorURL {
  local($anchorText,$class,$method,$variable) = @_;
  return("<FONT COLOR = \"800080\"><A NAME = \"$class:$method:$variable\">$anchorText</A></FONT>");
}

sub linkURL {
  local($linkText,$fileName,$class,$method,$variable) = @_;
  return("<A HREF = \"$fileName#$class:$method:$variable\">$linkText</A>");
}

sub checkIfVariableUse {
        local ($stuff,$candidateName,$remainder) = @_;
        if ($methodVariableList{$candidateName}){  # if it's a method variable
                return "$stuff$openMethodVariable$candidateName$closeMethodVariable$remainder";
        } elsif ($classVariableList{$candidateName}) {  # if it's a class variable
                return "$stuff$openClassVariable$candidateName$closeClassVariable$remainder";
        } elsif (($candidateName =~ /^\d+$/)||($candidateName =~ /amp|lt|gt|quot/)){  # if it is &quot; or a number, (or empty...)
                return "$stuff$dummy$candidateName$dummy$remainder";
        } elsif ($remainder eq '(') { #This means that it's almost certainly a method call
                return "$stuff$openMethodCall$candidateName$closeMethodCall$remainder";
        } elsif ($primitiveTypes{$candidateName}) { #casting/ array declarations/ whatever
                return "$stuff$primitiveTypes{$candidateName}$remainder";
        } elsif ($remainder eq '[') { #This means that it's probably an array ref for a superclass
                return "$stuff$openClassVariable$candidateName$closeClassVariable$remainder";
        }                
 print "$stuff $candidateName $remainder\n" if $debug1;
                return "$stuff$dummy$candidateName$dummy$remainder";
        return "$stuff$openSomethingElse$candidateName$closeSomethingElse$remainder";
}

# sub findVariableUse {
#       print $_ if s/([\. \(\)\+\*\-\/\=])(\b\w+\b)([\.\(\)\;\, \=\+\-\*\/])/&checkIfVariableUse($1,$2,$3)/ge;
# }

sub findVariableUse {
        while (/[^><]\b\w+\b[^><]/) {
                s/([^><])(\b\w+\b)([^><])/&checkIfVariableUse($1,$2,$3)/ge;
        }
        print $_ if $debug2;
        s/$dummy//g;
}

sub variableMarkup {  # shoves the variable into a couple of data structures that
                                          # later tell me what is the scope and type of the variable
        local($variableName,$thisVariableType) = @_;    

        $variableType{"$className:$methodName:$variableName"} = "$thisVariableType";

        if ($methodName) {
                $methodVariableList{$variableName} = $variableName;
        } else {
                $classVariableList{$variableName} = $variableName;
        }
        
}

sub markupConstructors {
        s/(=\s*$openKeyword?new$closeKeyword?\s+)(\w+)([^\(><]*\()/$1$openConstructorCall$2$closeConstructorCall$3/g;
        print $_ if $debug5;
}

sub findVariableDeclaration {
#       This Matches the second word before a , ; = or ) [ which should be the varType.
        if (s/(\b\w+)(\s+\w+\s*[=,[;\)])/$openVariableType$1$closeVariableType$2/){
                $variableType = $1;
                print $_ if ((/\[/) && $debug3);
                if (/=/){ 
                        while (s/\b(\w+)\b([^=>,<]*\s*=)/$openVariableName$1$closeVariableName$2/){
                                $variableName = $1;
                                print "variable name: $variableName\n" if ((/\[/) && $debug3);
                                print $_ if ((/\[/) && $debug3);
                                &variableMarkup($variableName,$variableType);
                        }
                        &markupConstructors if /new/;
                } else {
                        while (s/\b(\w+)(\s*[,;\)\[])/$openVariableName$1$closeVariableName$2/){
                                $variableName = $1;
                                print "variable name: $variableName\n" if  ((/\[/) && $debug3);
                                if (/(\w+)(\s+$openVariableName)/) { #I.e., we just matched inside methodArgs
                                        $variableType = $1;
                                        $remainder = $2;
                                        s/$&/$openVariableType$variableType$closeVariableType$remainder/;
                                } 
                                &variableMarkup($variableName,$variableType);
                        }
                }
        }
}

sub htmlchar {
        #Filters out characters that will screw up the HTML browser
  s/&/&amp;/g;
  s/\</&lt;/g;
  s/\>/&gt;/g;
  s/\"/&quot;/g;
}

sub findMethodDeclaration {
#       print "class $className  ";
        s/(\b\w+)(\s*)\(/$openMethodName$1$closeMethodName$2$openMethodArguments(/;
        $methodName = $1;
        s/(\b\w+)(\s+$openMethodName)/$openMethodType$1$closeMethodType$2/ if (!($methodName eq $className)); #find method type if it isn't a constructor.
# print $_ if $debug6;
        $methodData{"$className:$methodName"} = $file;

        @methodList = (@methodList,$methodName);
        
        $foundMethodArgs = 0;
}

sub findRestOfMethodDeclaration {
        $foundMethodArgs = s/\)/\)$closeMethodArguments/ if ($methodName && !$foundMethodArgs);
        $inMethod = s/\{/$openMethod\{/ if ($foundMethodArgs && !$inMethod);
}

sub findExtends {
        if (s/(\bextends\s+)(\w+\b)/$1$openExtends$2$closeExtends/) {
                $extendsWeb{$className} = $2;
        } elsif  (s/(\bextends$closeKeyword\s+)(\w+\b)/$1$openExtends$2$closeExtends/) {
                $extendsWeb{$className} = $2;
        }
        if (s/(\bimplements$closeKeyword\s+)(\w+\b)/$1$openImplements$2$closeImplements/) {
                $implementsWeb{$className} = $2;
                print &_ if $debug10;
                while (s/($closeImplements,\s+)(\w+\b)/$1$openImplements$2$closeImplements/g) {
                        $implementsWeb{$className} .= ",$2";
                }
        } elsif (s/(\bimplements\s+)(\w+\b)/$1$openImplements$2$closeImplements/) {
                $implementsWeb{$className} = $2;
                print $_ if $debug10;
                while (s/($closeImplements,\s+)(\w+\b)/$1$openImplements$2$closeImplements/g) {
                        $implementsWeb{$className} .= ",$2";
                }
        }
}

sub findRestofClassHeader  {
        $foundOpenClass = s/(\{)/$openClass$1/; # tells us if we've made the match
        $braceCount = foundOpenClass;
}

sub processClassHeader {
        $foundClass = 1;
        s/(\bclass\s+)(\w+\b)/$1$openClassName$2$closeClassName/; # get the class name
        $className = $2;
        $classData{$className} = $file;
        &findRestofClassHeader;
        &findExtends;
}
sub findImports {
        s/(import$closeKeyword\s+)(\w+)(\s*;)/$1$openImports$2$closeImports$3/;
        $imp = $2;
        if ($importsData{$className}) {
                $importsData{$className} .= ",$imp";
        } else {
                $importsData{$className} = "$imp";
        }
}

sub findInterface {
        if (s/(\binterface$closeKeyword?\s+)(\w+\b)/$1$openClassName$2$closeClassName/) { # get the interface name
                $className = $2;
                $classData{$className} = $file;
                &findRestofClassHeader;
                $foundInterface = 1;
                print $_ if (/interface/ && $debug6);
        }
}       
        
        
sub process {
        if (s/(\/{2,2}.*\n)//) { # picks out // comments, comments go in tail
#               mungeing things so that I don't go analyzing what's in // comments
                $tail = "$openComment$1$closeComment\n";
                $tail =~ s/\n//;
        }
        
        
        &processClassHeader if (/\bclass\b/ && !$foundClass);           
        &findExtends if ($foundClass && !$foundOpenClass);
        &findRestofClassHeader if ($foundClass && !$foundOpenClass);

#       Find and markup Keywords
        s/(\b\w+\b)/$keyWords{$1}?$keyWords{$1}:$1/ge;

        if (!$foundClass) {
                &findImports;
                &findInterface;
                print "$className\n" if ($debug6 && $foundInterface);
        } 
        if ($foundInterface) {
                &findMethodDeclaration;
                print "$methodName\n" if ($debug6 && $methodName);
                $methodName = "";                       
                &findVariableDeclaration;

                if (/\}/) {
                        s/\}([^\}]*$)/}$closeClass$1/;   # figure out how to only do this to the last one.
                        $foundClass = 0;
                        $foundInterface = 0;
                        $foundOpenClass = 0;
                        %classVariableList = ();
                        $inMethod = 0;
                        $methodName = "";
                        %methodVariableList = ();
                }

        } elsif ($foundClass && $foundOpenClass) {
                $lineBraceCount = 0;
                $lineBraceCount++ while /\{|\}/g;  # if line brace count == 3, then I'm in one of those } xx{} blocks that are such a pain.  
                $braceCount-- while /\}/g;

                if ($braceCount == 1 && $lineBraceCount != 3){                          
                        &findMethodDeclaration if (!(m/=/) && (m/\(/));                         
                        &findVariableDeclaration;
                        &findRestOfMethodDeclaration;
                }

                $braceCount++ while /\{/g;

                &findVariableDeclaration if $inMethod;
                &findVariableUse if $inMethod;
                &markupConstructors if /new/;
                                
                if ($braceCount == 0){
                        s/\}([^\}]*$)/}$closeClass$1/;   # figure out how to only do this to the last one.
                        $foundClass = 0;
                        $foundOpenClass = 0;
                        %classVariableList = ();
                } elsif (($braceCount == 1) && $inMethod){
                        if (s/\}([^\}]*$)/}$closeMethod$1/){   # figure out how to only do this to the last one.
                                $inMethod = 0; 
                                $methodName = "";
                                %methodVariableList = ();
                        }
                }
        }
}


sub parseFile {
        $tail = "";
        while (<JAVA>){
                &htmlchar;
                s/\t/    /g; # tabs to spaces
                if ($inComment){
                        $inComment = 0 if s/(.*$cc)/$1$closeComment/;
                } else {
                        unless (s/($c.*$cc)/$openComment$1$closeComment/g){ # picks out one line /* */ comments
#                                Checks to see if we are at the beginning of a multiline comment
                                $inComment = s/($c.*)/$openComment$1/;
                                }
                }
                
                &process if !($inComment);
                push (@theFile, $_.=$tail);
                $tail = "";
        }
}

sub writeHeader {
        print HTMLFILE '<HTML> <body bgcolor = "FFFFFF"> <PRE>';
        print HTMLFILE "\n";
}       

sub writeFooter {
        print HTMLFILE '</PRE></BODY></HTML> ';
        print HTMLFILE "\n";
}       

sub methodResolver {  #Tries to resolve the $function starting with class $vType
                                          #returns null if it fails (i.e. the function is in an unindexed superclass
        local($vType,$function) = @_;
        local $link;
        
        print "$vType:$function, " if ($debug7 && /setPainted/);
        print $methodData{"$vType:$function"} if ($debug7 && /setPainted/);
        print "  $extendsWeb{$vType}\n"  if ($debug7 && /setPainted/);
        while ($extendsWeb{$vType} || $methodData{"$vType:$function"}) {
                if ($methodData{"$vType:$function"}) {
                        $link = &linkURL($function,$htmlLinkFile{$classData{$vType}},$vType,$function);
                        print "$link \n" if ($debug7 && /setPainted/);
                        return "$link";
                        last;  #this really shouldn't be necessary.....
                } else {
                        $vType = $extendsWeb{$vType};
                }
        }
        return "";
}

sub variableResolver {  #Tries to resolve the $variableName starting with class $vType
                                                #returns null if it fails (i.e. the variable is in an unindexed superclass

        local($vType,$variableName) = @_;

        print " type: $vType :$function  extends: $extendsWeb{$vType}  file:" if $debug4;
        print  $variableType{"$vType::$function"} if $debug4;
        print "\n" if $debug4;
        
        while ($extendsWeb{$vType} || $variableType{"$vType:$nothing:$function"}) {
                if ($variableType{"$vType:$nothing:$function"}) {
                        local($link) = &linkURL($function,$htmlLinkFile{$classData{$vType}},$vType,"",$function);
                        return "$link";
                        print "ummmmmm we've got a problem. last after return, variable part of close variable parse\n";
                        last;  #this really shouldn't be necessary.....
                } else {
                        $vType = $extendsWeb{$vType};
                }
        }
        print " type: $vType :$function  extends: $extendsWeb{$vType}  file:" if $debug4;
        print  $variableType{"$vType::$function"} if $debug4;
        print "\n" if $debug4;
        return "";
}

sub closeVariableParse {
        local($variableName,$methodOrClass,$function,$rest) = @_;
        local($link) = "";
        
        if ($methodOrClass =~ /$closeMethodVariable/) {
                $localMethodName = $methodName;
        } else {
                $localMethodName = "";
        }
        
        print $_ if (/\bthis\b/ && $debug8);
        print "$variableName;$methodOrClass;$function;$rest\n" if (/\bthis\b/ && $debug8);
        
        if ($variableName =~ /this/) {  # reference this.variable
                $vType = $className;
                print "this occurance $className $_ " if $debug8; 
        } elsif ($classData{$variableName}) {  #Static variable usage/method call
                $vType = $classData{$variableName};
                print "static occurance $className $_ " if $debug8; 
        } elsif ($variableName eq 'super') {  #Static variable usage/method call
                $vType = extendsWeb{$classData{$variableName}};
                print "super occurance $className $_ " if $debug8; 
        }else {
                $vType = $variableType{"$className:$localMethodName:$variableName"};
        }

        print "$variableName$methodOrClass$function$rest, $vType, $extendsWeb{$vType} \n" if (($function =~ /gr/) && $debug4);

        #       If we don't get anything this is a type that we don't know about.
        if (!($classData{$vType})) {
                return "$variableName$methodOrClass$openUnknownCall$function$closeUnknownCall$rest";
        }

        if ($rest =~ /\(/ ) {  # if we have a ( we have what looks like a method call.
                $link = &methodResolver($vType,$function);
                return "$variableName$methodOrClass$link$rest" if ($link);
        } else {
                $link = &variableResolver($vType,$function);  
                return "$variableName$methodOrClass$link$rest" if ($link);
        }
        print "fell through\n" if $debug4;
        return "$variableName$methodOrClass$function$rest"; #I may get here if I have a 
                                                                                                                #method that is provided by a non indexed superclass
}

sub localMethods {
        local ($name) = @_;
        local ($link);
        $link = &methodResolver($className,$1);
        print "$link \n" if (/setPainted/ && $debug7);
        if ($link) {
                return $link;
        } else {
                return $name;
        }
}

sub parseMethods {
        local $link;
        while ($_ = shift(@theFile)) {
                $className = $1 if /$openClassName(\w+\b)/;
                $methodName = $1 if /$openMethodName(\w+\b)/;
                $className = "" if /$closeClass/;
                $methodName = "" if /$closeMethod/;

#               print "$_" if /(\b\w+)($closeMethodVariable\.)(\w+\b)([^\<])/;
                s/(this$closeKeyword\.)($openMethodVariable)(\w+\b)($closeMethodVariable)/$1$openClassVariable$3$closeClassVariable/g;
                print $_ if (/\bthis\b/ && (!(/COMMENT/)) && $debug9);

                s/(this$closeKeyword\.)(\w+\b)(\s*\S?)/&closeVariableParse($1,"",$2,$3)/ge;


                s/(\b\w+)($closeMethodVariable\.)(\w+\b)(\s*\S?)/&closeVariableParse($1,$2,$3,$4)/ge;
                s/(\b\w+)($closeMethodVariable\.$openMethodCall)(\w+\b)($closeMethodCall\s*\S?)/&closeVariableParse($1,$2,$3,$4)/ge;

                s/(\b\w+)($closeClassVariable\.)(\w+\b)(\s*\S?)/&closeVariableParse($1,$2,$3,$4)/ge;            
                s/(\b\w+)($closeClassVariable\.$openMethodCall)(\w+\b)($closeMethodCall\s*\S?)/&closeVariableParse($1,$2,$3,$4)/ge;

                
#               s/(\b\w+)(.$openMethodCall)(\w+)($closeMethodCall\s*\S?)/&closeVariableParse($1,$2,$3,$4)/ge;
# 
                s/$openMethodCall(\w+)$closeMethodCall/&localMethods($1)/ge;
                print "$_" if ( $debug7 && /setPainted/);
                
                push (@tempTheFile, $_ ); #.= $tail);
#               $tail = "";
        }
        @theFile = @tempTheFile;
        @tempTheFile = ();
}

sub markupFile {
        $className = "";
        $methodName = "";
        open (HTMLFILE,$htmlSaveFile{$file}) || die "Could not open the HTML file for $file\n";
        print "Writing $htmlSaveFile{$file}\n";
        &writeHeader;
        while ($_ = shift(@theFile)) {
                s/$openComment/$openCommentMarkup/g;    #dealing with comment tags
                s/$closeComment/$closeCommentMarkup/g;
                if (s/$openClassName(\w+)$closeClassName/&anchorURL($1,$1)/e){
                        $className = $1;        # anchor and naming for classes
                }
                if (s/$openMethodName(\w+)$closeMethodName/&anchorURL($1,$className,$1)/e){
                        $methodName = $1;       #anchor and naming for methods
                }
                s/$openVariableType(\w+)$closeVariableType/$classData{$1}?&linkURL($1,$htmlLinkFile{$classData{$1}},$1):$primitiveTypes{$1}?$primitiveTypes{$1}:$1/ge;
# write something that grabe variable types of double etc and colorizes them.
#               Anchors for variable declarations
                s/$openVariableName(\w+)$closeVariableName/&anchorURL($1,$className,$methodName,$1)/ge;
                s/$openClassVariable(\w+)$closeClassVariable/&linkURL($1,"",$className,"",$1)/ge;
                s/$openMethodVariable(\w+)$closeMethodVariable/&linkURL($1,"",$className,$methodName,$1)/ge;            
                s/$openExtends(\w+)$closeExtends/$classData{$1}?&linkURL($1,$htmlLinkFile{$classData{$1}},$1):$1/ge;
                s/$openImplements(\w+)$closeImplements/$classData{$1}?&linkURL($1,$htmlLinkFile{$classData{$1}},$1):$1/ge;
                s/$openConstructorCall(\w+)$closeConstructorCall/$classData{$1}?&linkURL($1,$htmlLinkFile{$classData{$1}},$1,$1):"$openConstructorCall$1$closeConstructorCall"/ge;
                s/$openMethodType(\w+)$closeMethodType/$classData{$1}?&linkURL($1,$htmlLinkFile{$classData{$1}},$1):$primitiveTypes{$1}?$primitiveTypes{$1}:$1/ge;

                s/$openMethodArguments//g;
                s/$closeMethodArguments//g;
                s/$openClass//g;
                s/$openMethod//g;

                s/$openKeyword/$openKeywordMarkup/g;
                s/$closeKeyword/$closeKeywordMarkup/g;

                s/$openImports(\w+)$closeImports/$classData{$1}?&linkURL($1,$htmlLinkFile{$classData{$1}},$1):$1/ge;

                $className = "" if s/$closeClass//;     # closing off the class
                $methodName = "" if s/$closeMethod//;   # closing off the methods
                        
                print HTMLFILE $_;
        }
        &writeFooter;
        close(HTMLFILE);                        
}


if ($printVariables) {
        print " variables:\n\n";
        foreach $variable (sort keys(%variableType)) {
                print  "   $variable,  $variableType{$variable} \n";
        }
        print "\n";
}
# 
# print "\nmethods\n\n";
# foreach $method (sort keys(%methodData)) {
#       print  "   $method : $methodData{$method}\n";
# }
# print "\n";
# 
# print "extendsWeb\n";
# foreach $key (sort keys(%extendsWeb)) {
#       print  "   $key : $extendsWeb{$key}\n";
# }
# print "\n";
# 
# print "ClassData\n";
# foreach $class (sort keys(%classData)) {
#       print  "   $class : $classData{$class}\n";
# }
# print "\n";
# 
# print "Link info \n";
# foreach $key (sort keys(%htmlLinkFile)) {
#       print  "   $key : $htmlLinkFile{$key}\n";
# }
# print "\n";
# 
# print "Save info \n";
# foreach $key (sort keys(%htmlSaveFile)) {
#       print  "   $key : $htmlSaveFile{$key}\n";
# }
# print "\n";



