gatherHeaderDoc.pl [plain text]
use Cwd;
use File::Find;
use File::Copy;
my $pathSeparator;
my $isMacOS;
my $scriptDir;
my $framesetFileName;
my $masterTOCFileName;
BEGIN {
if ($^O =~ /MacOS/i) {
$pathSeparator = ":";
$isMacOS = 1;
} else {
$pathSeparator = "/";
$isMacOS = 0;
}
}
use strict;
use FindBin qw ($Bin);
use lib "$Bin"."$pathSeparator"."Modules";
use HeaderDoc::DocReference;
use HeaderDoc::Utilities qw(findRelativePath safeName getAPINameAndDisc printArray printHash updateHashFromConfigFiles getHashFromConfigFile);
my $debugging = 1;
my $localConfigFileName = "headerDoc2HTML.config";
my $preferencesConfigFileName = "com.apple.headerDoc2HTML.config";
my $homeDir = (getpwuid($<))[7];
my $usersPreferencesPath = $homeDir.$pathSeparator."Library".$pathSeparator."Preferences";
my @configFiles = ($Bin.$pathSeparator.$localConfigFileName, $usersPreferencesPath.$pathSeparator.$preferencesConfigFileName);
my %config = (
defaultFrameName => "index.html",
masterTOCName => "MasterTOC.html"
);
%config = &updateHashFromConfigFiles(\%config,\@configFiles);
if (defined $config{"defaultFrameName"}) {
$framesetFileName = $config{"defaultFrameName"};
}
if (defined $config{"masterTOCName"}) {
$masterTOCFileName = $config{"masterTOCName"};
}
my @inputFiles;
my $inputDir;
if (($ $inputDir = $ARGV[0];
$inputDir =~ s|(.*)/$|$1|; if ($inputDir !~ /^\//) { # not absolute path -- !!! should check for ~
my $cwd = cwd();
$inputDir = $cwd.$pathSeparator.$inputDir;
}
&find({wanted => \&getFiles, follow => 1}, $inputDir);
} else {
die "You must specify a single input directory for processing.\n";
}
unless (@inputFiles) { print "No valid input files specified. \n\n";};
sub getFiles {
my $filePath = $File::Find::name;
my $fileName = $_;
if ($fileName =~ /$framesetFileName/) {
push(@inputFiles, $filePath);
}
}
my @headerFramesetRefs;
my @classFramesetRefs;
my $oldRecSep = $/;
undef $/;
foreach my $file (@inputFiles) {
open (INFILE, "<$file") || die "Can't open $file: $!\n";
my $fileString = <INFILE>;
close INFILE;
if ($fileString =~ /<--\s+(headerDoc\s*=.*?)-->/) {
my $fullComment = $1;
my @pairs = split(/;/, $fullComment);
my $docRef = HeaderDoc::DocReference->new;
$docRef->path($file);
foreach my $pair (@pairs) {
my ($key, $value) = split(/=/, $pair);
$key =~ s/^\s+|\s+$//;
$value =~ s/^\s+|\s+$//;
SWITCH: {
($key =~ /headerDoc/) &&
do {
$docRef->type($value);
last SWITCH;
};
($key =~ /name/) &&
do {
$docRef->name($value);
last SWITCH;
};
}
}
my $tmpType = $docRef->type();
if ($tmpType eq "Header") {
push (@headerFramesetRefs, $docRef);
} elsif ($tmpType eq "CPPClass") {
push (@classFramesetRefs, $docRef);
} else {
my $tmpName = $docRef->name();
my $tmpPath = $docRef->path();
print "Unknown type '$tmpType' for document with name '$tmpName' and path '$tmpPath'\n";
}
}
}
$/ = $oldRecSep;
if (scalar(@headerFramesetRefs) + scalar(@classFramesetRefs)) {
&printMasterTOC();
&addTopLinkToFramesetTOCs();
} else {
print "gatherHeaderDoc.pl: No HeaderDoc framesets found--returning\n" if ($debugging);
return;
}
exit 0;
sub printMasterTOC {
my $outputDir = $inputDir;
my $masterTOC = $outputDir.$pathSeparator. $masterTOCFileName;
my $headersLinkString= '';
my $classesLinkString = '';
my $fileString;
my $localDebug = 0;
foreach my $ref (sort objName @headerFramesetRefs) {
my $name = $ref->name();
my $path = $ref->path();
my $tmpString = &getLinkToFramesetFrom($masterTOC, $path, $name);
$headersLinkString .= $tmpString;
}
print "\$headersLinkString is '$headersLinkString'\n" if ($localDebug);
foreach my $ref (sort objName @classFramesetRefs) {
my $name = $ref->name();
my $path = $ref->path();
my $tmpString = &getLinkToFramesetFrom($masterTOC, $path, $name);
$classesLinkString .= $tmpString;
}
if (($localDebug) && length($classesLinkString)) {print "\$classesLinkString is '$classesLinkString'\n";};
my $htmlHeader = "<html><head><title>Header Documentation</title></head><body bgcolor=\"#cccccc\"><h1>Header Documentation</h1><hr><br>\n";
my $headerSection = "<h2>Headers</h2>\n<blockquote>\n".$headersLinkString."\n</blockquote>\n";
my $classesSection = '';
if (length($classesLinkString)) {
$classesSection = "<h2>Classes</h2>\n<blockquote>\n".$classesLinkString."\n</blockquote>\n";
}
my $htmlFooter = "</body>\n</html>\n";
$fileString = $htmlHeader.$headerSection.$classesSection.$htmlFooter;
print "gatherHeaderDoc.pl: writing master TOC to $masterTOC\n" if ($localDebug);
open(OUTFILE, ">$masterTOC") || die "Can't write $masterTOC.\n";
print OUTFILE $fileString;
close OUTFILE;
}
sub addTopLinkToFramesetTOCs {
my $masterTOC = $inputDir.$pathSeparator. $masterTOCFileName;
my $tocFileName = "toc.html";
my @allDocRefs;
push(@allDocRefs, @headerFramesetRefs);
push(@allDocRefs, @classFramesetRefs);
my $localDebug = 0;
foreach my $ref (@allDocRefs) {
my $name = $ref->name();
my $type = $ref->type();
my $path = $ref->path();
my $tocFile = $path; my $fsName = quotemeta($framesetFileName);
$tocFile =~ s/$fsName$/toc.html/;
if (-e "$tocFile" ) {
my $oldRecSep = $/;
undef $/; open(INFILE, "<$tocFile") || die "Can't read file $tocFile.\n";
my $fileString = <INFILE>;
close INFILE;
$/ = $oldRecSep;
my $uniqueMarker = "headerDoc=\"topLink\"";
if ($fileString !~ /$uniqueMarker/) { my $relPathToMasterTOC = &findRelativePath($tocFile, $masterTOC);
my $topLink = "\n<font size=\"-2\"><a href=\"$relPathToMasterTOC\" target=\"_top\" $uniqueMarker>[Top]</a></font><br>\n";
$fileString =~ s/(<body[^>]*>)/$1$topLink/i;
open (OUTFILE, ">$tocFile") || die "Can't write file $tocFile.\n";
print OUTFILE $fileString;
close (OUTFILE);
}
} elsif ($debugging) {
print "--> '$tocFile' doesn't exist!\n";
print "Cannot add [top] link for frameset doc reference:\n";
print " name: $name\n";
print " type: $type\n";
print " path: $path\n";
}
}
}
sub getLinkToFramesetFrom {
my $masterTOCFile = shift;
my $dest = shift;
my $name = shift;
my $linkString;
my $relPath = &findRelativePath($masterTOCFile, $dest);
$linkString = "<a href=\"$relPath\" target =\"_top\">$name</a><br>\n";
return $linkString;
}
sub objName { uc($a->name()) cmp uc($b->name());
}