MayaChemTools

   1 #!/usr/bin/perl -w
   2 #
   3 # $RCSfile: SDFilesToHTML.pl,v $
   4 # $Date: 2015/02/28 20:46:20 $
   5 # $Revision: 1.50 $
   6 #
   7 # Author: Manish Sud <msud@san.rr.com>
   8 #
   9 # Copyright (C) 2015 Manish Sud. All rights reserved.
  10 #
  11 # This file is part of MayaChemTools.
  12 #
  13 # MayaChemTools is free software; you can redistribute it and/or modify it under
  14 # the terms of the GNU Lesser General Public License as published by the Free
  15 # Software Foundation; either version 3 of the License, or (at your option) any
  16 # later version.
  17 #
  18 # MayaChemTools is distributed in the hope that it will be useful, but without
  19 # any warranty; without even the implied warranty of merchantability of fitness
  20 # for a particular purpose.  See the GNU Lesser General Public License for more
  21 # details.
  22 #
  23 # You should have received a copy of the GNU Lesser General Public License
  24 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
  25 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
  26 # Boston, MA, 02111-1307, USA.
  27 #
  28 
  29 use strict;
  30 use FindBin; use lib "$FindBin::Bin/../lib";
  31 use Getopt::Long;
  32 use File::Basename;
  33 use File::Spec;
  34 use Text::ParseWords;
  35 use Benchmark;
  36 use Cwd;
  37 use FileUtil;
  38 use SDFileUtil;
  39 use TextUtil;
  40 use HTMLUtil;
  41 
  42 my($ScriptName, %Options, $StartTime, $EndTime, $TotalTime);
  43 
  44 # Autoflush STDOUT
  45 $| = 1;
  46 
  47 # Starting message...
  48 $ScriptName = basename($0);
  49 print "\n$ScriptName: Starting...\n\n";
  50 $StartTime = new Benchmark;
  51 
  52 # Get the options and setup script...
  53 SetupScriptUsage();
  54 if ($Options{help} || @ARGV < 1) {
  55   die GetUsageFromPod("$FindBin::Bin/$ScriptName");
  56 }
  57 
  58 my(@SDFilesList);
  59 @SDFilesList = ExpandFileNames(\@ARGV, "sdf sd");
  60 
  61 #Make sure appropriate mode specific option values are specified...
  62 print "Processing options...\n";
  63 my(%OptionsInfo);
  64 ProcessOptions();
  65 
  66 # Collect information about SD files...
  67 print "Checking input SD file(s)...\n";
  68 my(%SDFilesInfo);
  69 RetrieveSDFilesInfo();
  70 SetupMultipleTablesAndMiscInfo();
  71 
  72 # Generate output files...
  73 my($FileIndex);
  74 if (@SDFilesList > 1) {
  75   print "\nProcessing SD files...\n";
  76 }
  77 for $FileIndex (0 .. $#SDFilesList) {
  78   if ($SDFilesInfo{FileOkay}[$FileIndex]) {
  79     print "\nProcessing file $SDFilesList[$FileIndex]...\n";
  80     GenerateHTMLTable($FileIndex);
  81   }
  82 }
  83 print "\n$ScriptName:Done...\n\n";
  84 
  85 $EndTime = new Benchmark;
  86 $TotalTime = timediff ($EndTime, $StartTime);
  87 print "Total time: ", timestr($TotalTime), "\n";
  88 
  89 ###############################################################################
  90 
  91 # Generate HTML table(s)...
  92 sub GenerateHTMLTable {
  93   my($Index) = @_;
  94 
  95   if ($SDFilesInfo{MultipleHTMLTables}[$Index]) {
  96     GenerateMultipleHTMLTables($Index);
  97   }
  98   else {
  99     GenerateOneHTMLTable($Index);
 100   }
 101 }
 102 
 103 # Generate one HTML table...
 104 sub GenerateOneHTMLTable {
 105   my($Index) = @_;
 106   my($SDFile, $TopHTMLDir, $HTMLFile, $StartCmpdNum, $EndCmpdNum, $CSSFile, $CSSRef, $CSSFilePath, $TableNum);
 107 
 108   $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . ".html";
 109   $SDFile = $SDFilesList[$Index];
 110 
 111   # Setup data directories...
 112   ($TopHTMLDir) = SetupDataDirs($Index);
 113 
 114   # Setup stylesheet file...
 115   $CSSRef = "";
 116   if ($Options{stylesheet} =~ /^new$/i) {
 117     $CSSFile = $SDFilesInfo{HTMLRoot}[$Index] . ".css"; $CSSRef = ".\/" . "$CSSFile";
 118     $CSSFilePath = "$TopHTMLDir" . "\/" . $CSSFile;
 119     GenerateStyleSheetFile($CSSFilePath);
 120   }
 121   elsif ($Options{stylesheet} =~ /^old$/i) {
 122     $CSSRef = $Options{stylesheetname};
 123   }
 124 
 125   # Set HTML file location...
 126   $HTMLFile = "$TopHTMLDir" . "\/" . $HTMLFile;
 127 
 128   print "Generating HTML file $HTMLFile...\n";
 129   open HTMLFILE, ">$HTMLFile" or die "Error: Can't open $HTMLFile: $! \n";
 130   open SDFILE, "$SDFile" or die "Error: Can't open $SDFile: $! \n";
 131 
 132   # Write out HTML page header...
 133   print HTMLFILE SetupHTMLPageHeader($SDFilesInfo{HTMLTitle}[$Index], $CSSRef, $OptionsInfo{TopHTMLDirStrViewerJSFileRef});
 134 
 135   if ($OptionsInfo{StrViewerJSFileRef}) {
 136     print HTMLFILE SetupStrViewerJSInitCmd($OptionsInfo{StrViewerType}, $OptionsInfo{TopHTMLDirStrViewerCodeBase});
 137   }
 138 
 139   # Setup page title...
 140   if ($OptionsInfo{TitleDisplay}) {
 141     print HTMLFILE SetupHTMLPageTitle($SDFilesInfo{HTMLTitle}[$Index]);
 142   }
 143   else {
 144     print HTMLFILE SetupHTMLEmptyLines(1);
 145   }
 146 
 147   # Start the table...
 148   print HTMLFILE SetupHTMLAlignmentBegin("center");
 149   print HTMLFILE SetupHTMLTableHeader($OptionsInfo{TableBorder}, $OptionsInfo{TableCellPadding}, $OptionsInfo{TableCellSpacing});
 150 
 151   # Generate table rows...
 152   $StartCmpdNum = 1;
 153   $EndCmpdNum = $SDFilesInfo{CmpdCount}[$Index];
 154   $TableNum = 1;
 155   GenerateTableRows($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, \*SDFILE, \*HTMLFILE);
 156 
 157   # Finish up the table...
 158   print HTMLFILE SetupHTMLTableEnd();
 159   print HTMLFILE SetupHTMLAlignmentEnd("center");
 160 
 161   # Write out HTML page end...
 162   print HTMLFILE SetupHTMLPageEnd($OptionsInfo{FooterMsg});
 163 
 164   close HTMLFILE;
 165   close SDFILE;
 166 }
 167 
 168 # Generate multiple tables...
 169 sub GenerateMultipleHTMLTables {
 170   my($Index) = @_;
 171   my($TopHTMLDir, $SubHTMLDir, $SDFile, $HTMLFile, $TableNum, $TableCount, $TableIndex, $TableStartCmpdNum, $TableEndCmpdNum, $PrintMsg, $CSSFile, $CSSRef, $CSSFilePath, $NewStyleSheet, $StrViewerCodeBase, $StrViewerJSFileRef);
 172 
 173   # Open SD file...
 174   $SDFile = $SDFilesList[$Index];
 175   open SDFILE, "$SDFile" or die "Error: Can't open $SDFile: $! \n";
 176 
 177   # Set up data directories to hold various html files...
 178   ($TopHTMLDir, $SubHTMLDir) = SetupDataDirs($Index);
 179 
 180   # Create stylesheet file...
 181   $CSSRef = "";
 182   $NewStyleSheet = 0;
 183   if ($Options{stylesheet} =~ /^new$/i) {
 184     $NewStyleSheet = 1;
 185     $CSSFile = $SDFilesInfo{HTMLRoot}[$Index] . ".css";
 186     $CSSFilePath = "$TopHTMLDir" . "\/" . $CSSFile;
 187     GenerateStyleSheetFile($CSSFilePath);
 188   }
 189   elsif ($Options{stylesheet} =~ /^old$/i) {
 190     $CSSRef = $Options{stylesheetname};
 191   }
 192 
 193   $PrintMsg = 1;
 194   # Generate HTML files for all the tables...
 195   $TableCount = $SDFilesInfo{TableCount}[$Index];
 196   for $TableNum (1 .. $TableCount) {
 197     $TableIndex = $TableNum - 1;
 198     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$TableIndex];
 199     $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$TableIndex];
 200     $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$TableIndex];
 201 
 202     # Setup file name...
 203     if ($TableNum == 1) {
 204       $HTMLFile = "$TopHTMLDir" . "\/" . $HTMLFile;
 205       print "Generating HTML file $HTMLFile...\n";
 206     }
 207     else {
 208       $HTMLFile = "$SubHTMLDir" . "\/" . $HTMLFile;
 209       if ($PrintMsg) {
 210         $PrintMsg = 0;
 211         if ($TableCount == 2) {
 212           print "Generating HTML file $HTMLFile...\n";
 213         }
 214         else {
 215           print "Generating ", ($TableCount - 1), " other HTML files: $SubHTMLDir\/$SDFilesInfo{HTMLRoot}[$Index]\*.html...\n";
 216         }
 217       }
 218     }
 219     # Setup stylesheet reference...
 220     if ($NewStyleSheet) {
 221       $CSSRef = ($TableNum == 1) ? ".\/" : "..\/";
 222       $CSSRef .= $CSSFile;
 223     }
 224 
 225     open HTMLFILE, ">$HTMLFile" or die "Error: Can't open $HTMLFile: $! \n";
 226     # Write out HTML page header...
 227     $StrViewerJSFileRef = ($TableNum == 1) ? $OptionsInfo{TopHTMLDirStrViewerJSFileRef} : $OptionsInfo{SubHTMLDirStrViewerJSFileRef};
 228     print HTMLFILE SetupHTMLPageHeader($SDFilesInfo{HTMLTitle}[$Index], $CSSRef, $StrViewerJSFileRef);
 229 
 230     if ($OptionsInfo{StrViewerJSFileRef}) {
 231       $StrViewerCodeBase = ($TableNum == 1) ? $OptionsInfo{TopHTMLDirStrViewerCodeBase} : $OptionsInfo{SubHTMLDirStrViewerCodeBase};
 232       print HTMLFILE SetupStrViewerJSInitCmd($OptionsInfo{StrViewerType}, $StrViewerCodeBase);
 233     }
 234 
 235     # Set up the navigation links for this table...
 236     if ($OptionsInfo{NavLinksAtTop}) {
 237       WriteNavigationLinks($Index, $TableNum, \*HTMLFILE);
 238     }
 239     # Setup page title...
 240     if ($OptionsInfo{TitleDisplay}) {
 241       print HTMLFILE SetupHTMLPageTitle($SDFilesInfo{HTMLTitle}[$Index]);
 242     }
 243     else {
 244       print HTMLFILE SetupHTMLEmptyLines(1);
 245     }
 246 
 247     # Start the table...
 248     print HTMLFILE SetupHTMLAlignmentBegin("center");
 249     print HTMLFILE SetupHTMLTableHeader($OptionsInfo{TableBorder}, $OptionsInfo{TableCellPadding}, $OptionsInfo{TableCellSpacing});
 250 
 251     # Generate table content...
 252     GenerateTableRows($Index, $TableNum, $TableStartCmpdNum, $TableEndCmpdNum, \*SDFILE, \*HTMLFILE);
 253 
 254     # Finish up the table...
 255     print HTMLFILE SetupHTMLTableEnd();
 256     print HTMLFILE SetupHTMLAlignmentEnd("center");
 257 
 258     # Set up the navigation links for this table...
 259     if ($OptionsInfo{NavLinksAtBottom}) {
 260       print HTMLFILE SetupHTMLEmptyLines(1);
 261       WriteNavigationLinks($Index, $TableNum, \*HTMLFILE);
 262     }
 263 
 264     # Write out HTML page end...
 265     print HTMLFILE SetupHTMLPageEnd($OptionsInfo{FooterMsg});
 266     close HTMLFILE;
 267   }
 268   close SDFILE;
 269 
 270 }
 271 
 272 # Generate table content...
 273 sub GenerateTableRows {
 274   my($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef) = @_;
 275 
 276   if ($OptionsInfo{StructuresOnlyMode}) {
 277     WriteRowStructures($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef);
 278   }
 279   else {
 280     WriteColLabels($Index, $SDFileRef, $HTMLFileRef);
 281     WriteRowValues($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef);
 282   }
 283 }
 284 
 285 # Create stylesheet file...
 286 sub GenerateStyleSheetFile {
 287   my($CSSFile) = @_;
 288     print "Generating stylesheet file $CSSFile...\n";
 289     open CSSFILE, ">$CSSFile" or die "Error: Can't open $CSSFile: $! \n";
 290     print CSSFILE SetupHTMLStyleSheetTags();
 291     close CSSFILE;
 292 }
 293 
 294 # Write out table header using column labels...
 295 sub WriteColLabels {
 296   my($Index, $SDFileRef, $HTMLFileRef) = @_;
 297 
 298   my(@ColLabels, $Label);
 299   print $HTMLFileRef $SDFilesInfo{TableRowHeaderTags};
 300 
 301   # Write out structure label...
 302   $Label = "Structure";
 303   print $HTMLFileRef SetupHTMLTableRowHeaderValue($Label);
 304 
 305   # Write out field values..
 306   @ColLabels = @{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]};
 307   for $Label (@ColLabels) {
 308     print $HTMLFileRef SetupHTMLTableRowHeaderValue($Label);
 309   }
 310   print $HTMLFileRef $SDFilesInfo{RowEndTags};
 311 }
 312 
 313 # Write out the rows value...
 314 sub WriteRowValues {
 315   my($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef) = @_;
 316   my($BackgroundColor, $FontColor, $RowNum, $CmpdNum, $CmpdString, @CmpdLines, $Label, %DataFieldValues, $Value);
 317 
 318   $RowNum = 0;
 319   for $CmpdNum ($StartCmpdNum .. $EndCmpdNum) {
 320     $RowNum++;
 321     $CmpdString = ReadCmpdString($SDFileRef);
 322     if ($OptionsInfo{ShadeRowsStatus}) {
 323       print $HTMLFileRef ($RowNum % 2) ? $SDFilesInfo{BgFilledOddRowHeaderTags} : $SDFilesInfo{BgFilledEvenRowHeaderTags};
 324     }
 325     else {
 326       print $HTMLFileRef $SDFilesInfo{RowHeaderTags};
 327     }
 328     @CmpdLines = split "\n", $CmpdString;
 329     %DataFieldValues = GetCmpdDataHeaderLabelsAndValues(\@CmpdLines);
 330 
 331     # Setup structure column...
 332     SetupStructureColumn($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 333     # Write out field values..
 334     for $Label (@{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]}) {
 335       $Value = (IsNotEmpty($DataFieldValues{$Label})) ? $DataFieldValues{$Label} : "";
 336       $BackgroundColor = ""; $FontColor = "";
 337       if ($OptionsInfo{HighlightStatus}) {
 338         if (exists($OptionsInfo{SpecifiedHighlightDataFieldLabelsMap}{$Label})) {
 339           ($BackgroundColor, $FontColor) = GetValueHighlightColors($Label, $Value);
 340         }
 341       }
 342       print $HTMLFileRef SetupHTMLTableRowDataValue($Value, $BackgroundColor, $FontColor);
 343     }
 344     print $HTMLFileRef $SDFilesInfo{RowEndTags};
 345   }
 346 }
 347 
 348 # Write only structures...
 349 sub WriteRowStructures {
 350   my($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef) = @_;
 351   my($CmpdNum, $CmpdString, $StartRowFlag, $ColNum, $RowNum, $RowBgColor, $RowStartTags, $ColumnHeaderTags, $ColumnEndTags, $CmpdDataFieldValue, $CmpdHTMLFileRef, $Value);
 352 
 353   $StartRowFlag = 1; $ColNum = 0; $RowNum = 0;
 354   $ColumnHeaderTags = SetupHTMLTableColumnHeader();
 355   $ColumnEndTags = SetupHTMLTableColumnEnd();
 356 
 357   if ($OptionsInfo{StructuresOnlyMode} && !$OptionsInfo{TableBorder} && ($OptionsInfo{OddRowsShadeColor} =~ /^(#ffffff|white)$/i)) {
 358     print $HTMLFileRef SetupHTMLTableRowHeader($OptionsInfo{RowHAlignment}, $OptionsInfo{TableHeaderRowColor}, $OptionsInfo{RowVAlignment});
 359     $Value = SetupHTMLTableRowDataValue("");
 360     print $HTMLFileRef InsertHTMLTags($Value, "colspan", "$OptionsInfo{StrTableCols}");
 361     print $HTMLFileRef $SDFilesInfo{RowEndTags};
 362   }
 363 
 364   for $CmpdNum ($StartCmpdNum .. $EndCmpdNum) {
 365     $CmpdString = ReadCmpdString($SDFileRef);
 366     if ($StartRowFlag) {
 367       $StartRowFlag = 0;
 368       $RowNum++;
 369       if ($OptionsInfo{ShadeRowsStatus}) {
 370         print $HTMLFileRef ($RowNum % 2) ? $SDFilesInfo{BgFilledOddRowHeaderTags} : $SDFilesInfo{BgFilledEvenRowHeaderTags};
 371       }
 372       else {
 373         print $HTMLFileRef $SDFilesInfo{RowHeaderTags};
 374       }
 375     }
 376     $ColNum++;
 377 
 378     $CmpdDataFieldValue = "";
 379     if ($OptionsInfo{CmpdDataField}) {
 380       my($CmpdDataField, @CmpdLines, %DataFieldValues);
 381       $CmpdDataField = $OptionsInfo{CmpdDataField};
 382       @CmpdLines = split "\n", $CmpdString;
 383       %DataFieldValues = GetCmpdDataHeaderLabelsAndValues(\@CmpdLines);
 384       if (exists($DataFieldValues{$CmpdDataField}) && length($DataFieldValues{$CmpdDataField})) {
 385         $CmpdDataFieldValue = $DataFieldValues{$CmpdDataField};
 386         if ($OptionsInfo{CmpdDataFieldLabel} =~ /^yes$/i) {
 387           $CmpdDataFieldValue = "${CmpdDataField}: ${CmpdDataFieldValue}";
 388         }
 389         # Make sure it's not to looong...
 390         if (length($CmpdDataFieldValue) > 30) {
 391           $CmpdDataFieldValue = substr($CmpdDataFieldValue, 0, 30) . "...";
 392         }
 393       }
 394     }
 395     if ($CmpdDataFieldValue) {
 396       $RowBgColor = "";
 397       if ($OptionsInfo{ShadeRowsStatus}) {
 398         $RowBgColor = ($RowNum % 2) ? $OptionsInfo{OddRowsShadeColor} : $OptionsInfo{EvenRowsShadeColor};
 399       }
 400       $RowStartTags = SetupHTMLTableRowHeader($OptionsInfo{CmpdDataFieldAlignment}, $RowBgColor, "middle");
 401       # Start  a new table in current column...
 402       print $HTMLFileRef $ColumnHeaderTags;
 403       print $HTMLFileRef SetupHTMLAlignmentBegin("center");
 404       print $HTMLFileRef SetupHTMLTableHeader(0, 0, 0);
 405 
 406       if ($OptionsInfo{CmpdDataFieldPosition} =~ /^top$/i ) {
 407         # Add an empty row...
 408         print $HTMLFileRef $RowStartTags;
 409         print $HTMLFileRef SetupHTMLTableRowDataValue("");
 410         print $HTMLFileRef $SDFilesInfo{RowEndTags};
 411 
 412         # Display the label value...
 413         print $HTMLFileRef $RowStartTags;
 414         $CmpdHTMLFileRef = SetupCompoundSummaryFileAndLink($Index, $TableNum, $CmpdString, $CmpdNum);
 415         $Value = SetupHTMLHRef("$CmpdDataFieldValue", $CmpdHTMLFileRef, "Compound Summary");
 416         print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
 417         print $HTMLFileRef $SDFilesInfo{RowEndTags};
 418       }
 419       # Display the structure...
 420       print $HTMLFileRef SetupHTMLTableRowHeader("center", $RowBgColor, "middle");
 421       SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 422       print $HTMLFileRef $SDFilesInfo{RowEndTags};
 423 
 424       if ($OptionsInfo{CmpdDataFieldPosition} =~ /^bottom$/i ) {
 425         # Display the label value...
 426         print $HTMLFileRef $RowStartTags;
 427         $CmpdHTMLFileRef = SetupCompoundSummaryFileAndLink($Index, $TableNum, $CmpdString, $CmpdNum);
 428         $Value = SetupHTMLHRef("$CmpdDataFieldValue", $CmpdHTMLFileRef, "Compound Summary");
 429         print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
 430         print $HTMLFileRef $SDFilesInfo{RowEndTags};
 431 
 432         # Add an empty row...
 433         print $HTMLFileRef $RowStartTags;
 434         print $HTMLFileRef SetupHTMLTableRowDataValue("");
 435         print $HTMLFileRef $SDFilesInfo{RowEndTags};
 436       }
 437 
 438       print $HTMLFileRef SetupHTMLTableEnd();
 439       print $HTMLFileRef SetupHTMLAlignmentEnd("center");
 440       print $HTMLFileRef $ColumnEndTags;
 441     }
 442     else {
 443       SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 444     }
 445 
 446     if ($ColNum == $OptionsInfo{StrTableCols}) {
 447       # Finish up the current row and get ready for starting a new row...
 448       print $HTMLFileRef $SDFilesInfo{RowEndTags};
 449       $ColNum = 0;
 450       $StartRowFlag = 1;
 451     }
 452   }
 453   if (!$StartRowFlag) {
 454     # Finish up an existing row...
 455     my($ColIndex, $Value);
 456     $Value = "";
 457     for $ColIndex ($ColNum .. ($OptionsInfo{StrTableCols} - 1) ) {
 458       print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
 459     }
 460     print $HTMLFileRef $SDFilesInfo{RowEndTags};
 461   }
 462 }
 463 
 464 # Setup structure column...
 465 sub SetupStructureColumn {
 466   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 467 
 468   if ($OptionsInfo{DisplayStructure}) {
 469     SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 470   }
 471   else {
 472     SetupStructureLink($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 473   }
 474 }
 475 
 476 # Setup structure display for compound summary page...
 477 sub SetupStructureDisplayForCmpdSummaryPage {
 478   my($Index, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 479   my($TableNum, $RowNum);
 480 
 481   # Use table num 0 to force usage of "../mol" prefix for all MOL file references. Row num
 482   # doesn't matter...
 483   $TableNum = 0;
 484   $RowNum = 1;
 485 
 486   $OptionsInfo{SettingUpCmpdSummaryPage} = 1;
 487 
 488   # Setup size and bgcolor parameters for linking structures...
 489   $OptionsInfo{StrViewerParams}{width} = $OptionsInfo{StrLinkWidth};
 490   $OptionsInfo{StrViewerParams}{height} = $OptionsInfo{StrLinkHeight};
 491   $OptionsInfo{StrViewerParams}{bgcolor} = $OptionsInfo{StrLinkBgColorSpecified};
 492 
 493   SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 494 
 495   # Reset size and bgcolor parameters back to displaying structures in tables...
 496   $OptionsInfo{StrViewerParams}{width} = $OptionsInfo{StrWidth};
 497   $OptionsInfo{StrViewerParams}{height} = $OptionsInfo{StrHeight};
 498   $OptionsInfo{StrViewerParams}{bgcolor} = $OptionsInfo{StrBgColorSpecified} ? $OptionsInfo{StrBgColorSpecified} : "";
 499 
 500   $OptionsInfo{SettingUpCmpdSummaryPage} = 0;
 501 }
 502 
 503 
 504 # Setup structure column display...
 505 sub SetupStructureDisplay {
 506   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 507   my($Nothing);
 508 
 509  STRVIEWERTYPE: {
 510     if ($OptionsInfo{StrViewerType} =~ /^JME$/i) { SetupJMEDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 511     if ($OptionsInfo{StrViewerType} =~ /^Jmol$/i) { SetupJmolDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 512     if ($OptionsInfo{StrViewerType} =~ /^Chime$/i) { SetupChimeDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 513     if ($OptionsInfo{StrViewerType} =~ /^(Chem3DActiveX|ChemDrawActiveX|ChemDrawPlugIn)$/i) { SetupCambridgeSoftDisplay($OptionsInfo{StrViewerType}, $Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 514     if ($OptionsInfo{StrViewerType} =~ /^MarvinView$/i) { SetupMarvinDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 515     if ($OptionsInfo{StrViewerType} =~ /^ViewerActiveX$/i) { SetupViewerAccelrysActiveXDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 516     $Nothing = 1;
 517   }
 518 }
 519 
 520 # Setup JME display...
 521 sub SetupJMEDisplay {
 522   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 523   my($MolString, $AppletBGColor, $Value, $ValueTag, $AppletName, $StrViewerCodeBase);
 524 
 525   $Value = "";
 526   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
 527   if (IsNotEmpty($MolString)) {
 528     $AppletBGColor = SetupStructureBGColor($RowNum);
 529     $MolString .= "$SDFilesInfo{MolEndTag}";
 530 
 531     # JME viewer doesn't appear to support "bgcolor" param. So, always use white background for
 532     # structure cell...
 533     $AppletName = "JME" . $CmpdNum;
 534     $OptionsInfo{StrViewerParams}{name} = $AppletName;
 535     if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
 536       if (!$OptionsInfo{StrBgColorSpecified}) {
 537         $OptionsInfo{StrViewerParams}{bgcolor} = $AppletBGColor;
 538       }
 539     }
 540     $StrViewerCodeBase = ($TableNum == 1) ? $OptionsInfo{TopHTMLDirStrViewerCodeBase} : $OptionsInfo{SubHTMLDirStrViewerCodeBase};
 541     $Value = SetupStrViewerJMEApplet($MolString, $StrViewerCodeBase, \%{$OptionsInfo{StrViewerParams}});
 542     $ValueTag = SetupHTMLTableRowDataValue($Value, $SDFilesInfo{White});
 543   }
 544   else {
 545     $ValueTag = SetupHTMLTableRowDataValue($Value);
 546   }
 547   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
 548     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 549   }
 550   print $HTMLFileRef $ValueTag;
 551 }
 552 
 553 # Setup Marvin display...
 554 sub SetupMarvinDisplay {
 555   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 556   my($MolString, $AppletBGColor, $Value, $ValueTag, $AppletName, $StrViewerCodeBase);
 557 
 558   $Value = "";
 559   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
 560   if (IsNotEmpty($MolString)) {
 561     $AppletBGColor = SetupStructureBGColor($RowNum);
 562     $MolString .= "$SDFilesInfo{MolEndTag}";
 563 
 564     $AppletName = "MView" . $CmpdNum;
 565     $OptionsInfo{StrViewerParams}{name} = $AppletName;
 566     if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
 567       if (!$OptionsInfo{StrBgColorSpecified}) {
 568         $OptionsInfo{StrViewerParams}{bgcolor} = $AppletBGColor;
 569       }
 570     }
 571     $StrViewerCodeBase = ($TableNum == 1) ? $OptionsInfo{TopHTMLDirStrViewerCodeBase} : $OptionsInfo{SubHTMLDirStrViewerCodeBase};
 572     $Value = SetupStrViewerMarvinViewApplet($MolString, $StrViewerCodeBase, \%{$OptionsInfo{StrViewerParams}});
 573     $ValueTag = SetupHTMLTableRowDataValue($Value);
 574   }
 575   else {
 576     $ValueTag = SetupHTMLTableRowDataValue($Value);
 577   }
 578   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
 579     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 580   }
 581   print $HTMLFileRef $ValueTag;
 582 }
 583 
 584 # Setup Jmol display...
 585 sub SetupJmolDisplay {
 586   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 587   my($MolString, $AppletBGColor, $Value, $ValueTag, $AppletName, $StrViewerCodeBase);
 588 
 589   $Value = ""; $ValueTag = "";
 590   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
 591   if (IsNotEmpty($MolString)) {
 592     $AppletBGColor = SetupStructureBGColor($RowNum);
 593     $MolString .= "$SDFilesInfo{MolEndTag}";
 594 
 595     # Make sure MolName line is not empty; otherwise, JMol doesn't display structure...
 596     my(@MolLines) = split "\n", $MolString;
 597     if (IsEmpty($MolLines[0])) {
 598       $MolLines[0] = "Cmpd${CmpdNum}";
 599       $MolString = join "\n", @MolLines;
 600     }
 601 
 602     # Setup the applet...
 603     $AppletName = "Jmol" . $CmpdNum;
 604     $OptionsInfo{StrViewerParams}{name} = $AppletName;
 605     if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
 606       if (!$OptionsInfo{StrBgColorSpecified}) {
 607         $OptionsInfo{StrViewerParams}{bgcolor} = $AppletBGColor;
 608       }
 609     }
 610     $StrViewerCodeBase = ($TableNum == 1) ? $OptionsInfo{TopHTMLDirStrViewerCodeBase} : $OptionsInfo{SubHTMLDirStrViewerCodeBase};
 611     $Value = SetupStrViewerJmolApplet($MolString, $StrViewerCodeBase, \%{$OptionsInfo{StrViewerParams}});
 612     $ValueTag = SetupHTMLTableRowDataValue($Value);
 613   }
 614   else {
 615     $ValueTag = SetupHTMLTableRowDataValue($Value);
 616   }
 617   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
 618     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 619   }
 620   print $HTMLFileRef $ValueTag;
 621 }
 622 
 623 # Setup Chime display...
 624 sub SetupChimeDisplay {
 625   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 626   my($MolString, $BGColor, $Value, $ValueTag, $MolFileRef);
 627 
 628   $Value = "";
 629   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
 630   if (IsNotEmpty($MolString)) {
 631     $BGColor = SetupStructureBGColor($RowNum);
 632     $MolString .= "$SDFilesInfo{MolEndTag}";
 633     # Write out MOL file...
 634     $MolFileRef = SetupMOLFile($Index, $TableNum, $MolString, $CmpdNum);
 635     # Setup the applet...
 636     if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
 637       if (!$OptionsInfo{StrBgColorSpecified}) {
 638         $OptionsInfo{StrViewerParams}{bgcolor} = $BGColor;
 639       }
 640     }
 641     $Value = SetupStrViewerChimePlugIn($MolFileRef, \%{$OptionsInfo{StrViewerParams}});
 642     $ValueTag = SetupHTMLTableRowDataValue($Value);
 643   }
 644   else {
 645     $ValueTag = SetupHTMLTableRowDataValue($Value);
 646   }
 647   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
 648     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 649   }
 650   print $HTMLFileRef $ValueTag;
 651 }
 652 
 653 # Setup displays for various viewers available from CambridgeSoft...
 654 sub SetupCambridgeSoftDisplay {
 655   my($ViewerType, $Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 656   my($MolString, $BGColor, $Value, $ValueTag, $MolFileRef, $Name);
 657 
 658   $Value = "";
 659   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
 660   if (IsNotEmpty($MolString)) {
 661     $BGColor = SetupStructureBGColor($RowNum);
 662     $MolString .= "$SDFilesInfo{MolEndTag}";
 663     # Write out MOL file...
 664     $MolFileRef = SetupMOLFile($Index, $TableNum, $MolString, $CmpdNum);
 665     # Setup the viewer...
 666     $Name = "CS" . $CmpdNum;
 667     if ($ViewerType =~ /^Chem3DActiveX$/) {
 668       # Use white background for Chem3D and cell; otherwise, it doesn't look good:
 669       # cell size is larger than Chem3D window size and different colors don't work
 670       $BGColor = $SDFilesInfo{White};
 671       $OptionsInfo{StrViewerParams}{name} = $Name;
 672       if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
 673         if (!$OptionsInfo{StrBgColorSpecified}) {
 674           $OptionsInfo{StrViewerParams}{bgcolor} = $BGColor;
 675         }
 676       }
 677       $Value = SetupStrViewerChem3DActiveX($MolFileRef, \%{$OptionsInfo{StrViewerParams}});
 678       $ValueTag = SetupHTMLTableRowDataValue($Value, $BGColor);
 679     }
 680     elsif ($ViewerType =~ /^ChemDrawActiveX$/i) {
 681       # BGColor is not supported. So, make it all white...
 682       $BGColor = $SDFilesInfo{White};
 683       $OptionsInfo{StrViewerParams}{name} = $Name;
 684       if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
 685         if (!$OptionsInfo{StrBgColorSpecified}) {
 686           $OptionsInfo{StrViewerParams}{bgcolor} = $BGColor;
 687         }
 688       }
 689       $Value = SetupStrViewerChemDrawActiveX($MolFileRef, \%{$OptionsInfo{StrViewerParams}});
 690       $ValueTag = SetupHTMLTableRowDataValue($Value, $BGColor);
 691     }
 692     elsif ($ViewerType =~ /^ChemDrawPlugIn$/i) {
 693       # BGColor is not supported. So, make it all white...
 694       $BGColor = $SDFilesInfo{White};
 695       if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
 696         if (!$OptionsInfo{StrBgColorSpecified}) {
 697           $OptionsInfo{StrViewerParams}{bgcolor} = $BGColor;
 698         }
 699       }
 700       $Value = SetupStrViewerChemDrawPlugIn($MolFileRef, \%{$OptionsInfo{StrViewerParams}});
 701       $ValueTag = SetupHTMLTableRowDataValue($Value, $BGColor);
 702     }
 703   }
 704   else {
 705     $ValueTag = SetupHTMLTableRowDataValue($Value);
 706   }
 707   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
 708     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 709   }
 710   print $HTMLFileRef $ValueTag;
 711 }
 712 
 713 # Setup Accelrys Viewer ActiveX display...
 714 sub SetupViewerAccelrysActiveXDisplay {
 715   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 716   my($MolString, $BGColor, $Value, $ValueTag, $Name, $MolFileRef);
 717 
 718   $Value = "";
 719   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
 720   if (IsNotEmpty($MolString)) {
 721     $BGColor = SetupStructureBGColor($RowNum);
 722     $MolString .= "$SDFilesInfo{MolEndTag}";
 723     # Write out MOL file. Accelrys ActiveX viewer doesn't load mol files with relative path names.
 724     # So, set up a complete path name for now; however, it may lead to issues during web
 725     # deployment.
 726     my($CompletePath) = 1;
 727     $MolFileRef = SetupMOLFile($Index, $TableNum, $MolString, $CmpdNum, $CompletePath);
 728     # Setup the viewer...
 729     $Name = "ViewerActiveX" . $CmpdNum;
 730     if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
 731       if (!$OptionsInfo{StrBgColorSpecified}) {
 732         $OptionsInfo{StrViewerParams}{bgcolor} = $BGColor;
 733       }
 734     }
 735     $OptionsInfo{StrViewerParams}{name} = $Name;
 736     $Value = SetupStrViewerAccelrysActiveX($MolFileRef, \%{$OptionsInfo{StrViewerParams}});
 737     $ValueTag = SetupHTMLTableRowDataValue($Value);
 738   }
 739   else {
 740     $ValueTag = SetupHTMLTableRowDataValue($Value);
 741   }
 742   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
 743     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 744   }
 745   print $HTMLFileRef $ValueTag;
 746 }
 747 
 748 
 749 # Setup structure background color...
 750 sub SetupStructureBGColor {
 751   my($RowNum) = @_;
 752   my($BGColor);
 753 
 754   $BGColor = "";
 755   if ($OptionsInfo{ShadeRowsStatus}) {
 756     $BGColor =  ($RowNum % 2) ? $OptionsInfo{OddRowsShadeColor} : $OptionsInfo{EvenRowsShadeColor};
 757   }
 758   else {
 759     $BGColor = $SDFilesInfo{White};
 760   }
 761   return $BGColor;
 762 }
 763 
 764 # Setup  MDL MOL file...
 765 sub SetupMOLFile {
 766   my($Index, $TableNum, $MolString, $CmpdNum, $CompletePath);
 767   my($SubMolDir, $MolFileName, $MolFile, $MolFileRef);
 768 
 769   $CompletePath = "";
 770   if (@_ == 5) {
 771     ($Index, $TableNum, $MolString, $CmpdNum, $CompletePath) = @_;
 772   }
 773   else {
 774     ($Index, $TableNum, $MolString, $CmpdNum) = @_;
 775   }
 776 
 777   $SubMolDir = $SDFilesInfo{SubMolDir}[$Index];
 778   $MolFileName = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $CmpdNum . ".mol";
 779   $MolFile = $SubMolDir . "\/" . $MolFileName;
 780 
 781   open MOLFILE, ">$MolFile" or die "Error: Can't open $MolFile: $! \n";
 782   print MOLFILE "$MolString\n";
 783   close MOLFILE;
 784 
 785   if ($CompletePath) {
 786     my($CWD, $NewCWD);
 787     $CWD = cwd();
 788     $NewCWD = ConvertCygwinPath($CWD);
 789     $MolFileRef = $NewCWD . "\/" . $SDFilesInfo{TopHTMLDir}[$Index] .  "\/mol\/$MolFileName" ;
 790   }
 791   else {
 792     $MolFileRef = ($TableNum == 1) ? ".\/mol\/$MolFileName" : "..\/mol\/$MolFileName";
 793   }
 794 
 795   return $MolFileRef;
 796 }
 797 
 798 # Setup a link to structure and other available information...
 799 sub SetupStructureLink {
 800   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 801   my($CmpdHTMLFileRef, $Value);
 802 
 803   $CmpdHTMLFileRef = SetupCompoundSummaryFileAndLink($Index, $TableNum, $CmpdString, $CmpdNum);
 804 
 805   if ($Options{strlinktype} =~ /^button$/i) {
 806     $Value = SetupHTMLButtonRef("View", $CmpdHTMLFileRef);
 807   }
 808   else {
 809     $Value = SetupHTMLHRef("View", $CmpdHTMLFileRef);
 810   }
 811   print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
 812 }
 813 
 814 # Setup HTML compound summary file and link...
 815 sub SetupCompoundSummaryFileAndLink {
 816   my($Index, $TableNum, $CmpdString, $CmpdNum) = @_;
 817   my($CmpdHTMLFile, $CmpdHTMLFileName, $CmpdHTMLFileRef, $CSSRef, @CmpdLines, $Label, @DataFieldLabels, %DataFieldValues, $Value, $Tag);
 818 
 819   # Setup compound file names...
 820   $CmpdHTMLFileName = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $CmpdNum . ".html";
 821   $CmpdHTMLFile = $SDFilesInfo{SubHTMLDir}[$Index] . "\/" . $CmpdHTMLFileName;
 822 
 823   # Setup stylesheet reference....
 824   $CSSRef = "";
 825   if ($Options{stylesheet} =~ /^old$/i) {
 826     $CSSRef = $Options{stylesheetname};
 827   }
 828   else {
 829     $CSSRef = "..\/" . $SDFilesInfo{HTMLRoot}[$Index] . ".css";
 830   }
 831 
 832   # Write out compound data in a new HTML file. For summary page, usage of even and odd row shade color
 833   # is reversed: it causes structure background to be white by default...
 834   open CMPDHTMLFILE, ">$CmpdHTMLFile" or die "Error: Can't open $CmpdHTMLFile: $! \n";
 835   print CMPDHTMLFILE SetupHTMLPageHeader($OptionsInfo{StrLinkTitle}, $CSSRef, $OptionsInfo{SubHTMLDirStrViewerJSFileRef});
 836 
 837   if ($OptionsInfo{StrViewerJSFileRef}) {
 838     print CMPDHTMLFILE SetupStrViewerJSInitCmd($OptionsInfo{StrViewerType}, $OptionsInfo{SubHTMLDirStrViewerCodeBase});
 839   }
 840 
 841   if ($OptionsInfo{StrLinkTitleDisplay}) {
 842     print CMPDHTMLFILE SetupHTMLPageTitle($OptionsInfo{StrLinkTitle}, "center");
 843   }
 844   else {
 845     print CMPDHTMLFILE SetupHTMLEmptyLines(1);
 846   }
 847   print CMPDHTMLFILE SetupHTMLAlignmentBegin("center");
 848 
 849   # Setup structure display ...
 850   print CMPDHTMLFILE SetupHTMLTableHeader(0, 5, 2);
 851 
 852   print CMPDHTMLFILE SetupHTMLTableRowHeader("center", "#ffffff", "middle");
 853 
 854   SetupStructureDisplayForCmpdSummaryPage($Index, $CmpdString, $CmpdNum, \*CMPDHTMLFILE);
 855   print CMPDHTMLFILE $SDFilesInfo{RowEndTags};
 856 
 857   if ($Options{strlinkmode} =~ /^plain$/i) {
 858     print CMPDHTMLFILE SetupHTMLTableRowHeader("center", $OptionsInfo{StrLinkShadeColor});
 859     $Tag = SetupHTMLTableRowDataValue("");
 860     print CMPDHTMLFILE $Tag;
 861     print CMPDHTMLFILE $SDFilesInfo{RowEndTags};
 862   }
 863 
 864   print CMPDHTMLFILE SetupHTMLTableRowHeader("left", "", "middle");
 865   # Start a new table with two columns, one each for data field labels and values, in
 866   # current column...
 867   print CMPDHTMLFILE SetupHTMLTableColumnHeader();
 868   print CMPDHTMLFILE SetupHTMLAlignmentBegin("left");
 869   print CMPDHTMLFILE SetupHTMLTableHeader(0, 5, 2);
 870 
 871   # Setup table for other available data...
 872   my($CmpdRowHeaderTags);
 873   $CmpdRowHeaderTags = SetupHTMLTableRowHeader("left", "", "middle");
 874 
 875   @CmpdLines = split "\n", $CmpdString;
 876 
 877   @DataFieldLabels = GetCmpdDataHeaderLabels(\@CmpdLines);
 878   %DataFieldValues = GetCmpdDataHeaderLabelsAndValues(\@CmpdLines);
 879 
 880   my($LabelWrapLength, $ValueWrapLength, $LabelColWidth);
 881   $LabelWrapLength = 30; $ValueWrapLength = 60; $LabelColWidth = 40;
 882 
 883   for $Label (@DataFieldLabels) {
 884     $Value =  $DataFieldValues{$Label};
 885     $Label .= ":";
 886     if ($Label && (length($Label) > $LabelWrapLength)) {
 887       $Label = WrapText($Label,  $LabelWrapLength, "<br>");
 888     }
 889     print CMPDHTMLFILE $CmpdRowHeaderTags;
 890     if ($Options{strlinkmode} =~ /^plain$/i) {
 891       $Tag = SetupHTMLTableRowDataValue($Label, "", "", 1);
 892     }
 893     else {
 894       $Tag = SetupHTMLTableRowDataValue($Label, $OptionsInfo{StrLinkShadeColor});
 895     }
 896     $Tag = InsertHTMLTags($Tag, "width", "$LabelColWidth");
 897     print CMPDHTMLFILE $Tag;
 898 
 899     if ($Value && (length($Value) >=$ValueWrapLength) && $Value !~ /a href/i) {
 900       $Value =~ s/(\r\n)|(\r)|\n//g;
 901       $Value = WrapText($Value,  $ValueWrapLength, "<br>");
 902     }
 903     $Tag = SetupHTMLTableRowDataValue($Value);
 904     print CMPDHTMLFILE $Tag;
 905     print CMPDHTMLFILE $SDFilesInfo{RowEndTags};
 906   }
 907 
 908   # Finish up table holding numerical data...
 909   print CMPDHTMLFILE SetupHTMLTableEnd();
 910   print CMPDHTMLFILE SetupHTMLAlignmentEnd("left");
 911   print CMPDHTMLFILE SetupHTMLTableColumnEnd();
 912   print CMPDHTMLFILE $SDFilesInfo{RowEndTags};
 913 
 914   # Finish up main table...
 915   print CMPDHTMLFILE SetupHTMLTableEnd();
 916   print CMPDHTMLFILE SetupHTMLAlignmentEnd("center");
 917 
 918   if ($OptionsInfo{StrLinkNavigation} && ($SDFilesInfo{CmpdCount}[$Index] > 1) ) {
 919     print CMPDHTMLFILE SetupHTMLEmptyLines(1);
 920     WriteCompoundSummaryNavigationLinks($Index, $TableNum, $CmpdNum, \*CMPDHTMLFILE);
 921   }
 922 
 923   print CMPDHTMLFILE SetupHTMLPageEnd($OptionsInfo{FooterMsg});
 924   close CMPDHTMLFILE;
 925 
 926   # Add a link to compound's HTML file in table cell...
 927   $CmpdHTMLFileRef = ($TableNum == 1) ? ".\/html\/" : ".\/";
 928   $CmpdHTMLFileRef .= $CmpdHTMLFileName;
 929 
 930   return $CmpdHTMLFileRef;
 931 }
 932 
 933 # Write navigation link information for compound summary page...
 934 sub WriteCompoundSummaryNavigationLinks {
 935   my($Index, $CurTableNum, $CurCmpdNum, $CmpdHTMLFileRef) = @_;
 936   my($FirstTableNum, $CurTableIndex, $FirstCmpdNum, $LastCmpdNum, $PreviousCmpdNum, $NextCmpdNum, $HTMLFile, $HTMLRefFile, $HTMLRefValue);
 937 
 938   $FirstTableNum = 1;
 939   $FirstCmpdNum = 1;
 940 
 941   $CurTableIndex = $CurTableNum - 1;
 942 
 943   if ($SDFilesInfo{MultipleHTMLTables}[$Index]) {
 944     my($FirstTableIndex, $LastTableNum, $LastTableIndex);
 945     $FirstTableIndex = $FirstTableNum - 1;
 946     $LastTableNum = $SDFilesInfo{TableCount}[$Index]; $LastTableIndex = $LastTableNum - 1;
 947     $LastCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$LastTableIndex];
 948   }
 949   else {
 950     $LastCmpdNum = $SDFilesInfo{CmpdCount}[$Index];
 951   }
 952 
 953   $PreviousCmpdNum = ($CurCmpdNum == $FirstCmpdNum) ? 0 : ($CurCmpdNum - 1);
 954   $NextCmpdNum = ($CurCmpdNum == $LastCmpdNum) ? 0 : ($CurCmpdNum + 1);
 955 
 956   my($InactiveLinkNumColor, $InactiveLinkFontBold) = ("#8e2323", "1");
 957   my($LinkTextColor, $LinkBGColor, $LinkFontBold) = ("", "", "0");
 958   my($BorderWidth, $CellPadding, $CellSpacing) = (0, 2, 2);
 959 
 960   # Start link table...
 961   print $CmpdHTMLFileRef SetupHTMLAlignmentBegin("center");
 962   print $CmpdHTMLFileRef SetupHTMLDivBegin("tablenav");
 963   print $CmpdHTMLFileRef  SetupHTMLTableHeader($BorderWidth, $CellPadding, $CellSpacing);
 964   print $CmpdHTMLFileRef $SDFilesInfo{RowHeaderTags};
 965 
 966   print $CmpdHTMLFileRef SetupHTMLTableRowDataValue("Compounds: ");
 967 
 968   # Setup a link to first compound...
 969   if ($CurCmpdNum != $FirstCmpdNum) {
 970     $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $FirstCmpdNum . ".html";
 971     $HTMLRefFile = "./${HTMLFile}";
 972     $HTMLRefValue = SetupHTMLHRef("First", $HTMLRefFile, "First Compound");
 973     print $CmpdHTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
 974   }
 975 
 976   # Setup a link to previous compund
 977   if ($PreviousCmpdNum) {
 978     $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $PreviousCmpdNum . ".html";
 979     $HTMLRefFile = "./${HTMLFile}";
 980     $HTMLRefValue = SetupHTMLHRef("Previous", $HTMLRefFile, "Previous Compound");
 981     print $CmpdHTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
 982   }
 983 
 984   # Setup a link to compound table...
 985   if ($SDFilesInfo{MultipleHTMLTables}[$Index]) {
 986     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$CurTableIndex];
 987   }
 988   else {
 989     $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . ".html";
 990   }
 991   $HTMLRefFile = (($CurTableNum == $FirstTableNum) ? "../" : "./") . $HTMLFile;
 992   $HTMLRefValue = SetupHTMLHRef("Table", $HTMLRefFile, "Table With This Compound");
 993   print $CmpdHTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
 994 
 995   # Setup a link to next compound...
 996   if ($NextCmpdNum) {
 997     $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $NextCmpdNum . ".html";
 998     $HTMLRefFile = "./${HTMLFile}";
 999     $HTMLRefValue = SetupHTMLHRef("Next", $HTMLRefFile, "Next Compound");
1000     print $CmpdHTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
1001   }
1002 
1003   # Setup a link to last compund
1004   if ($CurCmpdNum != $LastCmpdNum) {
1005     $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $LastCmpdNum . ".html";
1006     $HTMLRefFile = "./${HTMLFile}";
1007     $HTMLRefValue = SetupHTMLHRef("Last", $HTMLRefFile, "Last Compound");
1008     print $CmpdHTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
1009   }
1010 
1011   # Setup current table info text....
1012   print $CmpdHTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
1013   print $CmpdHTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
1014   print $CmpdHTMLFileRef SetupHTMLTableRowDataValue("Showing $CurCmpdNum of $LastCmpdNum");
1015 
1016   print $CmpdHTMLFileRef $SDFilesInfo{RowEndTags};
1017 
1018   # End link table...
1019   print $CmpdHTMLFileRef SetupHTMLTableEnd();
1020   print $CmpdHTMLFileRef SetupHTMLDivEnd();
1021   print $CmpdHTMLFileRef SetupHTMLAlignmentEnd("center");
1022 }
1023 
1024 # Setup navigation link information for each table.
1025 #
1026 # All table sets besides first and last have these links: FirstTable, Previous, Current-1,Current,Current+1,  Next, and LastTable
1027 # First set: Current, Next, and LastTable
1028 # Last set: FirstTable, Previous and Current.
1029 #
1030 sub WriteNavigationLinks {
1031   my($Index, $CurTableNum, $HTMLFileRef) = @_;
1032   my($TableNum, $StartTableNum, $EndTableNum, $TableIndex, $BorderWidth, $CellPadding, $CellSpacing,$HTMLFile, $HTMLRefFile, $RelativeFileDir, $HTMLRefValue, $FirstTableNum, $FirstTableIndex, $LastTableNum, $LastTableIndex, $TableStartCmpdNum, $TableEndCmpdNum, $LastCmpdNum, $BGColor, $LinksOffSet);
1033 
1034   $LinksOffSet = 10;
1035 
1036   $FirstTableNum = 1; $FirstTableIndex = $FirstTableNum - 1;
1037   $LastTableNum = $SDFilesInfo{TableCount}[$Index]; $LastTableIndex = $LastTableNum - 1;
1038   $LastCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$LastTableIndex];
1039 
1040   # Figure out which links to display for a particular table...
1041   $StartTableNum = $CurTableNum - $LinksOffSet + 1;
1042   $StartTableNum = ($StartTableNum < $FirstTableNum) ? $FirstTableNum : $StartTableNum;
1043   if ($CurTableNum < $LinksOffSet) {
1044     $EndTableNum = $LinksOffSet;
1045   }
1046   else {
1047     $EndTableNum = $CurTableNum + $LinksOffSet - 1;
1048   }
1049   $EndTableNum = ($EndTableNum > $LastTableNum) ? $LastTableNum : $EndTableNum;
1050 
1051   my($InactiveLinkNumColor, $InactiveLinkFontBold) = ("#8e2323", "1");
1052   my($LinkTextColor, $LinkBGColor, $LinkFontBold) = ("", "", "1");
1053 
1054   # Start link table...
1055   $BorderWidth = 0; $CellPadding = 2; $CellSpacing = 2;
1056   print $HTMLFileRef SetupHTMLAlignmentBegin("center");
1057   print $HTMLFileRef SetupHTMLDivBegin("tablenav");
1058   print $HTMLFileRef  SetupHTMLTableHeader($BorderWidth, $CellPadding, $CellSpacing);
1059   print $HTMLFileRef $SDFilesInfo{RowHeaderTags};
1060 
1061   if ($OptionsInfo{NavLinksTableInfo} && $OptionsInfo{NavLinksCmpdInfo}) {
1062     print $HTMLFileRef SetupHTMLTableRowDataValue("Showing table $CurTableNum of $LastTableNum");
1063     print $HTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
1064     print $HTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
1065   }
1066 
1067   print $HTMLFileRef SetupHTMLTableRowDataValue("Tables: ");
1068   # Setup a link to first table...
1069   if ($StartTableNum != $FirstTableNum) {
1070     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$FirstTableIndex];
1071     $HTMLRefFile = GetRelativeFileDir($CurTableNum, $FirstTableNum, $FirstTableNum) . $HTMLFile;
1072     $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$FirstTableIndex];
1073     $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$FirstTableIndex];
1074     $HTMLRefValue = SetupHTMLHRef("First", $HTMLRefFile, "First Table Containing Compounds $TableStartCmpdNum To $TableEndCmpdNum");
1075     print $HTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
1076   }
1077 
1078   # Setup link to previous table...
1079   if ($CurTableNum != $FirstTableNum) {
1080     my($PreviousTableNum, $PreviousTableIndex);
1081     $PreviousTableNum = $CurTableNum - 1; $PreviousTableIndex = $PreviousTableNum - 1;
1082     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$PreviousTableIndex];
1083     $HTMLRefFile = GetRelativeFileDir($CurTableNum, $PreviousTableNum, $FirstTableNum) . $HTMLFile;
1084     $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$PreviousTableIndex];
1085     $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$PreviousTableIndex];
1086     $HTMLRefValue = SetupHTMLHRef("Previous", $HTMLRefFile, "Previous Table Containing Compounds $TableStartCmpdNum To $TableEndCmpdNum");
1087     print $HTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
1088   }
1089 
1090   for $TableNum ($StartTableNum .. $EndTableNum) {
1091     $TableIndex = $TableNum - 1;
1092     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$TableIndex];
1093     if ($TableNum == $CurTableNum) {
1094       print $HTMLFileRef SetupHTMLTableRowDataValue($TableNum, $LinkBGColor, $InactiveLinkNumColor, $InactiveLinkFontBold);
1095     }
1096     else {
1097       # Setup the link...
1098       my($RefTitle);
1099       $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$TableIndex];
1100       $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$TableIndex];
1101       $RefTitle = AddNumberSuffix($TableNum) . " Table Containing Compounds $TableStartCmpdNum To $TableEndCmpdNum";
1102       $HTMLRefFile = GetRelativeFileDir($CurTableNum, $TableNum, $FirstTableNum) . $HTMLFile;
1103       $HTMLRefValue = SetupHTMLHRef($TableNum, $HTMLRefFile, $RefTitle);
1104       print $HTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue);
1105     }
1106   }
1107 
1108   # Setup link to next table...
1109   if ($CurTableNum != $LastTableNum) {
1110     my($NextTableNum, $NextTableIndex);
1111     $NextTableNum = $CurTableNum + 1; $NextTableIndex = $NextTableNum - 1;
1112     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$NextTableIndex];
1113     $HTMLRefFile = GetRelativeFileDir($CurTableNum, $NextTableNum, $FirstTableNum) . $HTMLFile;
1114     $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$NextTableIndex];
1115     $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$NextTableIndex];
1116     $HTMLRefValue = SetupHTMLHRef("Next", $HTMLRefFile, "Next Table Containing Compounds $TableStartCmpdNum To $TableEndCmpdNum");
1117     print $HTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
1118   }
1119 
1120   # Setup link to last table...
1121   if ($EndTableNum != $LastTableNum) {
1122     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$LastTableIndex];
1123     $HTMLRefFile = GetRelativeFileDir($CurTableNum, $LastTableNum, $FirstTableNum) . $HTMLFile;
1124     $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$LastTableIndex];
1125     $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$LastTableIndex];
1126     $HTMLRefValue = SetupHTMLHRef("Last", $HTMLRefFile, "Last Table Containing Compounds $TableStartCmpdNum To $TableEndCmpdNum");
1127     print $HTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
1128   }
1129   # Setup current table info text....
1130   print $HTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
1131   print $HTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
1132   $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$CurTableNum - 1];
1133   $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$CurTableNum - 1];
1134   if ($OptionsInfo{NavLinksCmpdInfo}) {
1135     print $HTMLFileRef SetupHTMLTableRowDataValue("Showing compounds $TableStartCmpdNum to $TableEndCmpdNum of $LastCmpdNum");
1136   }
1137   else {
1138     print $HTMLFileRef SetupHTMLTableRowDataValue("Showing table $CurTableNum of $LastTableNum");
1139   }
1140 
1141   print $HTMLFileRef $SDFilesInfo{RowEndTags};
1142   # End link table...
1143   print $HTMLFileRef SetupHTMLTableEnd();
1144   print $HTMLFileRef SetupHTMLDivEnd();
1145   print $HTMLFileRef SetupHTMLAlignmentEnd("center");
1146 }
1147 
1148 # Generate relative directory path...
1149 sub GetRelativeFileDir {
1150   my($FromTableNum, $ToTableNum, $FirstTableNum) = @_;
1151   my($RelativeFileDir) = "";
1152 
1153   if ($FromTableNum == $FirstTableNum) {
1154     $RelativeFileDir = ($ToTableNum == $FirstTableNum) ? ".\/" : ".\/html\/";
1155   }
1156   else {
1157     $RelativeFileDir = ($ToTableNum == $FirstTableNum) ? "..\/" : ".\/";
1158   }
1159   return $RelativeFileDir;
1160 }
1161 
1162 # Based on hightlight stype, return appropriate colors for background or text...
1163 sub GetValueHighlightColors {
1164   my($Label, $Value) = @_;
1165   my($DataType, $Criterion, $CriterionValue, $BgColor, $FontColor, $ValueOk, $Nothing);
1166 
1167   $BgColor = ""; $FontColor = "";
1168   $DataType = $OptionsInfo{SpecifiedHighlightDataFieldTypesMap}{$Label};
1169   $Criterion = $OptionsInfo{SpecifiedHighlightDataFieldCriteriaMap}{$Label};
1170   $CriterionValue = $OptionsInfo{SpecifiedHighlightDataFieldValueMap}{$Label};
1171 
1172   $ValueOk = 0;
1173   if ($DataType =~ /^numeric$/i) {
1174   NUMSWITCH: {
1175       if ($Criterion =~ /^ge$/i) { $ValueOk = ($Value >= $CriterionValue) ? 1 : 0; last NUMSWITCH; }
1176       if ($Criterion =~ /^le$/i) { $ValueOk = ($Value <= $CriterionValue) ? 1 : 0; last NUMSWITCH; }
1177       if ($Criterion =~ /^eq$/i) { $ValueOk = ($Value == $CriterionValue) ? 1 : 0; last NUMSWITCH; }
1178       $Nothing = 1;
1179     }
1180   }
1181   else {
1182   TEXTSWITCH: {
1183       if ($Criterion =~ /^ge$/i) { $ValueOk = ($Value ge $CriterionValue) ? 1 : 0; last TEXTSWITCH; }
1184       if ($Criterion =~ /^le$/i) { $ValueOk = ($Value le $CriterionValue) ? 1 : 0; last TEXTSWITCH; }
1185       if ($Criterion =~ /^eq$/i) { $ValueOk = ($Value eq $CriterionValue) ? 1 : 0; last TEXTSWITCH; }
1186       $Nothing = 1;
1187     }
1188   }
1189   $BgColor = $ValueOk ? $OptionsInfo{ValueOkColor} : $OptionsInfo{ValueNotOkColor};
1190   if ($Options{highlightstyle} =~ /^text$/i) {
1191     $BgColor = "";
1192     $FontColor = $ValueOk ? $OptionsInfo{ValueOkColor} : $OptionsInfo{ValueNotOkColor};
1193   }
1194   return ($BgColor, $FontColor);
1195 }
1196 
1197 #Make sure appropriate mode specific option values are specified...
1198 sub ProcessOptions {
1199 
1200   %OptionsInfo = ();
1201 
1202   $OptionsInfo{TitleDisplay} = ($Options{titledisplay} =~ /^yes$/i) ? 1 : 0;
1203 
1204   $OptionsInfo{RowHAlignment} = "left"; $OptionsInfo{RowVAlignment} = "middle";
1205   if (exists($Options{align})) {
1206     my (@AlignValues) = split ",", $Options{align};
1207     if (@AlignValues == 2) {
1208       $OptionsInfo{RowHAlignment} = $AlignValues[0];
1209       $OptionsInfo{RowVAlignment} = $AlignValues[1];
1210     }
1211     elsif (@AlignValues == 1) {
1212       $OptionsInfo{RowHAlignment} = $AlignValues[0];
1213     }
1214     else {
1215       die "Error: Invalid number of values, ", scalar(@AlignValues) , ", specified by \"-a --align\" option.\nIt must contain only one or two values.\n";
1216     }
1217     if ($OptionsInfo{RowHAlignment} !~ /^(left|center|right)$/i) {
1218       die "Error: The horizontal alignment value specified, $Options{align}, for option \"-a --align\" is not valid. Allowed values: left, center, or right\n";
1219     }
1220     if ($OptionsInfo{RowVAlignment} !~ /^(top|middle|bottom)$/i) {
1221       die "Error: The horizontal alignment value specified, $Options{align}, for option \"-a --align\" is not valid. Allowed values: top, middle, or bottom\n";
1222     }
1223   }
1224 
1225   $OptionsInfo{TableHeaderRowHAlignment} = "center"; $OptionsInfo{TableHeaderRowVAlignment} = "middle";
1226   if (exists($Options{headeralign})) {
1227     my (@AlignValues) = split ",", $Options{headeralign};
1228     if (@AlignValues == 2) {
1229       $OptionsInfo{TableHeaderRowHAlignment} = $AlignValues[0];
1230       $OptionsInfo{TableHeaderRowVAlignment} = $AlignValues[1];
1231     }
1232     elsif (@AlignValues == 1) {
1233       $OptionsInfo{TableHeaderRowHAlignment} = $AlignValues[0];
1234     }
1235     else {
1236       die "Error: Invalid number of values, ", scalar(@AlignValues) , ", specified by \"--headeralign\" option.\nIt must contain only one or two value.\n";
1237     }
1238     if ($OptionsInfo{TableHeaderRowHAlignment} !~ /^(left|center|right)$/i) {
1239       die "Error: The horizontal alignment value specified, $Options{headeralign}, for option \"--headeralign\" is not valid. Allowed values: left, center, or right\n";
1240     }
1241     if ($OptionsInfo{TableHeaderRowVAlignment} !~ /^(top|middle|bottom)$/i) {
1242       die "Error: The horizontal alignment value specified, $Options{headeralign}, for option \"-a --headeralign\" is not valid. Allowed values: top, middle, or bottom\n";
1243     }
1244   }
1245 
1246   if (exists($Options{border})) {
1247     $OptionsInfo{TableBorder} = $Options{border};
1248   }
1249   else {
1250     $OptionsInfo{TableBorder} = ($Options{mode} =~ /^(plain|highlight)$/i) || $Options{mode} =~ /^structuresonly$/i ? 1 : 0;
1251   }
1252   $OptionsInfo{TableCellPadding} = $Options{cellpadding};
1253   $OptionsInfo{TableCellSpacing} = $Options{cellspacing};
1254   $OptionsInfo{FooterMsg} = $Options{footer} ? $Options{footer} : "";
1255 
1256   if ($Options{headercolor}) {
1257     $OptionsInfo{TableHeaderRowColor} = $Options{headercolor};
1258   }
1259   else {
1260     $OptionsInfo{TableHeaderRowColor} = ($Options{mode} =~ /^plain$/i) ? "" : "#e0e9eb";
1261   }
1262 
1263   $OptionsInfo{NavLinksAtBottom} = 1; $OptionsInfo{NavLinksAtTop} = 0;
1264   if ($Options{displaylinks} =~ /^(both|top)$/i) {
1265     $OptionsInfo{NavLinksAtTop} = 1;
1266   }
1267   $OptionsInfo{NavLinksTableInfo} = 1; $OptionsInfo{NavLinksCmpdInfo} = 0;
1268   if ($Options{displaylinksinfo} =~ /^both$/i) {
1269     $OptionsInfo{NavLinksCmpdInfo} = 1;
1270     $OptionsInfo{NavLinksTableInfo} = 1;
1271   }
1272   elsif ($Options{displaylinksinfo} =~ /^compound$/i) {
1273     $OptionsInfo{NavLinksCmpdInfo} = 1;
1274     $OptionsInfo{NavLinksTableInfo} = 0;
1275   }
1276 
1277   if ($Options{stylesheet} =~ /^old$/i ) {
1278     if (!$Options{stylesheetname}) {
1279       die "Error: No stylesheet name specified using \"--stylesheetname\" option: It is required for \"old\" value of \"-s --stylesheet\" option. \n";
1280     }
1281   }
1282 
1283   my(@ColorValues);
1284   $OptionsInfo{ShadeRowsStatus} = 0;
1285   $OptionsInfo{OddRowsShadeColor} = "#ffffff";
1286   $OptionsInfo{EvenRowsShadeColor} = "#e0e9eb";
1287   if ($Options{shadecolor}) {
1288     # Make sure only one value is specified...
1289     @ColorValues = split ",", $Options{shadecolor};
1290     if (@ColorValues == 2) {
1291       $OptionsInfo{OddRowsShadeColor} = $ColorValues[0];
1292       $OptionsInfo{EvenRowsShadeColor} = $ColorValues[1];
1293     }
1294     else {
1295       die "Error: Invalid number of values, ", scalar(@ColorValues) , ", specified by \"--shadecolor\" option.\nIt must contain only two value.\n";
1296     }
1297   }
1298   if ($Options{mode} =~ /^(shade|shadedhighlight|shadedstructuresonly)$/i) {
1299     $OptionsInfo{ShadeRowsStatus} = 1;
1300   }
1301 
1302   $OptionsInfo{SettingUpCmpdSummaryPage} = 0;
1303   $OptionsInfo{StrLinkShadeColor} = (exists $Options{strlinkshadecolor}) ? $Options{strlinkshadecolor} : "#e0e9eb";
1304   $OptionsInfo{DisplayStructure} = ($Options{structure} =~ /^display$/i) ? 1 : 0;
1305   $OptionsInfo{StrViewerType} = $Options{strviewertype};
1306   $OptionsInfo{StrLinkNavigation} = ($Options{strlinknavigation} =~ /^yes$/i) ? 1 : 0;
1307   $OptionsInfo{StrLinkTitleDisplay} = ($Options{strlinktitledisplay} =~ /^yes$/i) ? 1 : 0;
1308   $OptionsInfo{StrLinkTitle} = (exists($Options{strlinktitle}) && length($Options{strlinktitle})) ? "$Options{strlinktitle}" : "Compound Summary";
1309 
1310   my($StrViewerEmbedUsingJS) = (($Options{strviewerembed} =~ /^javascript$/i) && ($OptionsInfo{StrViewerType} =~ /^(Jmol|MarvinView|ChemDrawPlugIn|ChemDrawActiveX|Chem3DActiveX)$/i )) ? 1 : 0;
1311 
1312   $OptionsInfo{StrTableRows} = 6; $OptionsInfo{StrTableCols} = 4;
1313   if ($Options{strtablesize}) {
1314     my(@StrTableSizeValues) = split ",", $Options{strtablesize};
1315     if (@StrTableSizeValues == 2) {
1316       $OptionsInfo{StrTableRows} = $StrTableSizeValues[0];
1317       $OptionsInfo{StrTableCols} = $StrTableSizeValues[1];
1318       if (!IsPositiveInteger($OptionsInfo{StrTableRows})) {
1319         die "Error: The first value specified, $OptionsInfo{StrTableRows},  for option \"--strtablesize\" is not valid: Allowed integer values: > 0.\n";
1320       }
1321       if (!IsPositiveInteger($OptionsInfo{StrTableCols})) {
1322         die "Error: The first value specified, $OptionsInfo{StrTableCols},  for option \"--strtablesize\" is not valid: Allowed integer values: > 0.\n";
1323       }
1324     }
1325     else {
1326       die "Error: Invalid number of values, ", scalar(@StrTableSizeValues), ", specified by \"--strtablesize\" option.\nIt must contain only two value for structuresonly \"-m --mode\" option.\n";
1327     }
1328   }
1329 
1330   # Setup applet information...
1331   $OptionsInfo{StrViewerCodeBase} = GetMayaChemToolsLibDirName() . "/Jmol";
1332   $OptionsInfo{TopHTMLDirStrViewerCodeBase} = $OptionsInfo{StrViewerCodeBase};
1333   $OptionsInfo{SubHTMLDirStrViewerCodeBase} = $OptionsInfo{StrViewerCodeBase};
1334 
1335   my($StrViewerAppletArchive, $StrViewerAppletCode) = SetupDefaultAppletArchiveAndCode($OptionsInfo{StrViewerType});
1336   if ($Options{strviewerconfig}) {
1337     my(@StrViewerConfigParts) = split ",", $Options{strviewerconfig};
1338     if (@StrViewerConfigParts >=1 && @StrViewerConfigParts <= 3) {
1339       if (@StrViewerConfigParts == 3) {
1340         $OptionsInfo{StrViewerCodeBase} = $StrViewerConfigParts[0];
1341         $StrViewerAppletArchive = $StrViewerConfigParts[1];
1342         $StrViewerAppletCode = $StrViewerConfigParts[2];
1343       }
1344       elsif (@StrViewerConfigParts == 2) {
1345         $OptionsInfo{StrViewerCodeBase} = $StrViewerConfigParts[0];
1346         $StrViewerAppletArchive = $StrViewerConfigParts[1];
1347         my($AppletArchive, $AppletCode) = SetupDefaultAppletArchiveAndCode($OptionsInfo{StrViewerType});
1348         $StrViewerAppletCode = $AppletCode;
1349       }
1350       else {
1351         $OptionsInfo{StrViewerCodeBase} = $StrViewerConfigParts[0];
1352         ($StrViewerAppletArchive, $StrViewerAppletCode) = SetupDefaultAppletArchiveAndCode($OptionsInfo{StrViewerType});
1353       }
1354     }
1355     else {
1356       die "Error: Invalid number of values, ", scalar(@StrViewerConfigParts), ", specified by \"--strviewerconfig\" option.\nNumver of allowed values:1 to 3 \n";
1357     }
1358   }
1359   else {
1360     if ($OptionsInfo{StrViewerType} =~ /^(JME|MarvinView)$/i ) {
1361       die "Error: No codebase specified using \"--strviewerconfig\" option for $OptionsInfo{StrViewerType} structure viewer\n";
1362     }
1363     if ($StrViewerEmbedUsingJS && $OptionsInfo{StrViewerType} !~ /^Jmol$/i) {
1364       die "Error: No codebase specified using \"--strviewerconfig\" option for javascript value of \"--strviewerembed\" option for $OptionsInfo{StrViewerType} structure viewer \n";
1365     }
1366   }
1367 
1368   if (-d $OptionsInfo{StrViewerCodeBase}) {
1369     # Change local code base direcrory name to a relative directory name based on the
1370     # current directory containing SD file; otherwise, Java applets and JavaScripts don't
1371     # get loaded into Firefox and Chrome browsers.
1372     #
1373     # For top and sub HTML directories, add prefix "../" and "../../" to relative path...
1374     $OptionsInfo{StrViewerCodeBase} = File::Spec->abs2rel($OptionsInfo{StrViewerCodeBase}, Cwd::cwd());
1375 
1376     $OptionsInfo{TopHTMLDirStrViewerCodeBase} = "../" . $OptionsInfo{StrViewerCodeBase};
1377     $OptionsInfo{SubHTMLDirStrViewerCodeBase} = "../../" . $OptionsInfo{StrViewerCodeBase};
1378   }
1379 
1380   # Setup structure viewer parameter information...
1381   %{$OptionsInfo{StrViewerParams}} = ();
1382   if ($Options{strviewerparams}) {
1383     my(@ParamsSplit, @ParamPairSplit, $ParamPair);
1384     #@ParamsSplit = split " ", $Options{strviewerparams};
1385     @ParamsSplit = quotewords(" ", 0, $Options{strviewerparams});
1386     for $ParamPair (@ParamsSplit) {
1387       @ParamPairSplit = split "=", $ParamPair;
1388       if (@ParamPairSplit == 2) {
1389         $OptionsInfo{StrViewerParams}{$ParamPairSplit[0]} = $ParamPairSplit[1];
1390       }
1391       else {
1392         die "Error: Invalid value, $ParamPair, specified by \"--strviewerparams\" option.\nValid values: name=value\n";
1393       }
1394     }
1395   }
1396 
1397   if ($OptionsInfo{StrViewerType} =~ /^(JME|Jmol|MarvinView)$/i ) {
1398     $OptionsInfo{StrViewerParams}{name} = $StrViewerAppletCode;
1399     $OptionsInfo{StrViewerParams}{archive} = $StrViewerAppletArchive;
1400     $OptionsInfo{StrViewerParams}{code} = $StrViewerAppletCode;
1401   }
1402   $OptionsInfo{StrWidth} = exists($OptionsInfo{StrViewerParams}{width}) ? $OptionsInfo{StrViewerParams}{width} : 250;
1403   $OptionsInfo{StrViewerParams}{width} = $OptionsInfo{StrWidth};
1404   $OptionsInfo{StrHeight} = exists($OptionsInfo{StrViewerParams}{height}) ? $OptionsInfo{StrViewerParams}{height} : 170;
1405   $OptionsInfo{StrViewerParams}{height} = $OptionsInfo{StrHeight};
1406 
1407   $OptionsInfo{StrLinkWidth} = 500;
1408   if (exists($OptionsInfo{StrViewerParams}{strlinkwidth})) {
1409     $OptionsInfo{StrLinkWidth} = $OptionsInfo{StrViewerParams}{strlinkwidth};
1410     $OptionsInfo{StrViewerParams}{strlinkwidth} = "";
1411   }
1412   $OptionsInfo{StrLinkHeight} = 295;
1413   if (exists($OptionsInfo{StrViewerParams}{strlinkheight})) {
1414     $OptionsInfo{StrLinkHeight} = $OptionsInfo{StrViewerParams}{strlinkheight};
1415     $OptionsInfo{StrViewerParams}{strlinkheight} = "";
1416   }
1417 
1418   $OptionsInfo{StrBgColorSpecified} = "";
1419   if (exists($OptionsInfo{StrViewerParams}{bgcolor})) {
1420     $OptionsInfo{StrBgColorSpecified} = $OptionsInfo{StrViewerParams}{bgcolor};
1421   }
1422 
1423   $OptionsInfo{StrLinkBgColorSpecified} = "#ffffff";
1424   if (exists($OptionsInfo{StrViewerParams}{strlinkbgcolor})) {
1425     $OptionsInfo{StrLinkBgColorSpecified} = $OptionsInfo{StrViewerParams}{strlinkbgcolor};
1426     $OptionsInfo{StrViewerParams}{strlinkbgcolor} = "";
1427   }
1428 
1429   # Setup Java Script usage...
1430   $OptionsInfo{StrViewerJSFileRef} = "";
1431   $OptionsInfo{TopHTMLDirStrViewerJSFileRef} = "";
1432   $OptionsInfo{SubHTMLDirStrViewerJSFileRef} = "";
1433 
1434   if ($StrViewerEmbedUsingJS) {
1435     my ($StrViewerJSFileName) = "";
1436     if ($Options{strviewerjsfile}) {
1437       $StrViewerJSFileName = $Options{strviewerjsfile};
1438     }
1439     else {
1440       if ($OptionsInfo{StrViewerType} =~ /^Jmol$/i) {
1441         $StrViewerJSFileName = "Jmol.js";
1442       }
1443       elsif ($OptionsInfo{StrViewerType} =~ /^MarvinView$/i) {
1444         $StrViewerJSFileName = "marvin.js";
1445       }
1446       elsif ($OptionsInfo{StrViewerType} =~ /^(ChemDrawPlugIn|ChemDrawActiveX)$/i) {
1447         $StrViewerJSFileName = "chemdraw.js";
1448       }
1449       elsif ($OptionsInfo{StrViewerType} =~ /^Chem3DActiveX$/i) {
1450         $StrViewerJSFileName = "chem3d.js";
1451       }
1452     }
1453     if ($StrViewerJSFileName) {
1454       $OptionsInfo{StrViewerParams}{usejavascript} = $StrViewerJSFileName;
1455       $OptionsInfo{StrViewerJSFileRef} = "$OptionsInfo{StrViewerCodeBase}" . "\/" . "$StrViewerJSFileName";
1456       $OptionsInfo{TopHTMLDirStrViewerJSFileRef} = "$OptionsInfo{TopHTMLDirStrViewerCodeBase}" . "\/" . "$StrViewerJSFileName";
1457       $OptionsInfo{SubHTMLDirStrViewerJSFileRef} = "$OptionsInfo{SubHTMLDirStrViewerCodeBase}" . "\/" . "$StrViewerJSFileName";
1458     }
1459   }
1460 
1461   # Check any other user specified parametrs applicable to all structure viewers...
1462 
1463   $OptionsInfo{StructuresOnlyMode} = 0;
1464   $OptionsInfo{MaxCmpdsPerTable} = ($Options{structure} =~ /^display$/i) ? 15 : 50;
1465   if (exists $Options{numcmpds}) {
1466     $OptionsInfo{MaxCmpdsPerTable} = $Options{numcmpds};
1467   }
1468   if ($Options{mode} =~ /^(structuresonly|shadedstructuresonly)$/i) {
1469     $OptionsInfo{MaxCmpdsPerTable} = ($OptionsInfo{MaxCmpdsPerTable} > 0) ? ($OptionsInfo{StrTableRows} * $OptionsInfo{StrTableCols}) : 0;
1470     $OptionsInfo{StructuresOnlyMode} = 1;
1471   }
1472   $OptionsInfo{CmpdDataField} = "";
1473   $OptionsInfo{CmpdDataFieldLabel} = "no";
1474   $OptionsInfo{CmpdDataFieldPosition} = "bottom";
1475   $OptionsInfo{CmpdDataFieldAlignment} = "center";
1476   if (exists($Options{cmpddatafield}) && length($Options{cmpddatafield})) {
1477     my (@CmpdDataFieldValues) = split ",", $Options{cmpddatafield};
1478     if (@CmpdDataFieldValues == 1) {
1479       $OptionsInfo{CmpdDataField} = $CmpdDataFieldValues[0];
1480     }
1481     elsif (@CmpdDataFieldValues == 2) {
1482       $OptionsInfo{CmpdDataField} = $CmpdDataFieldValues[0];
1483       $OptionsInfo{CmpdDataFieldLabel} = $CmpdDataFieldValues[1];
1484     }
1485     elsif (@CmpdDataFieldValues == 3) {
1486       $OptionsInfo{CmpdDataField} = $CmpdDataFieldValues[0];
1487       $OptionsInfo{CmpdDataFieldLabel} = $CmpdDataFieldValues[1];
1488       $OptionsInfo{CmpdDataFieldPosition} = $CmpdDataFieldValues[2];
1489     }
1490     elsif (@CmpdDataFieldValues == 4) {
1491       $OptionsInfo{CmpdDataField}  = $CmpdDataFieldValues[0];
1492       $OptionsInfo{CmpdDataFieldLabel} = $CmpdDataFieldValues[1];
1493       $OptionsInfo{CmpdDataFieldPosition} = $CmpdDataFieldValues[2];
1494       $OptionsInfo{CmpdDataFieldAlignment} = $CmpdDataFieldValues[3];
1495     }
1496     else {
1497       die "Error: Invalid number of values, ", scalar(@CmpdDataFieldValues) , ", specified by \"--cmpddatafield\" option.\nIt must contain only one, two, three, or four values.\n";
1498     }
1499     if ($OptionsInfo{CmpdDataFieldLabel} !~ /^(yes|no)$/ ) {
1500       die "Error: The label value specified, $Options{cmpddatafield}, for option \"--cmpddatafield\" is not valid. Allowed values: yes or no\n";
1501     }
1502     if ($OptionsInfo{CmpdDataFieldPosition} !~ /^(top|bottom)$/ ) {
1503       die "Error: The position value specified, $Options{cmpddatafield}, for option \"--cmpddatafield\" is not valid. Allowed values: top or bottom\n";
1504     }
1505     if ($OptionsInfo{CmpdDataFieldAlignment} !~ /^(left|center|right)$/ ) {
1506       die "Error: The alignment value specified, $Options{cmpddatafield}, for option \"--cmpddatafield\" is not valid. Allowed values: left, center, or right\n";
1507     }
1508   }
1509 
1510   # Process data fields to be displayed in tables...
1511   $OptionsInfo{SpecifiedDataFields} = exists($Options{datafields}) ? $Options{datafields} : "All";
1512 
1513   $OptionsInfo{ValueOkColor} = ""; $OptionsInfo{ValueNotOkColor} = ""; $OptionsInfo{HighlightStatus} = 0;
1514   if ($Options{mode} =~ /^(highlight|shadedhighlight)$/i) {
1515     my($HighlightMode, $HighlightBy);
1516     $HighlightMode = $Options{mode}; $HighlightBy = $Options{highlightby};
1517 
1518     $OptionsInfo{HighlightStatus} = 1;
1519     $OptionsInfo{ValueOkColor} = "#0fff0f";
1520     $OptionsInfo{ValueNotOkColor} = "#ff0f0f";
1521     if ($Options{highlightstyle} =~ /^text$/i) {
1522       $OptionsInfo{ValueOkColor} = "#0fbb0f";
1523       $OptionsInfo{ValueNotOkColor} = "#ff0f0f";
1524     }
1525     if ($Options{highlightcolor}) {
1526       # Make sure two values are specified...
1527       @ColorValues = split ",", $Options{highlightcolor};
1528       if (@ColorValues == 2) {
1529         $OptionsInfo{ValueOkColor} = $ColorValues[0];
1530         $OptionsInfo{ValueNotOkColor} = $ColorValues[1];
1531       }
1532       else {
1533         die "Error: Invalid number of values, ", scalar(@ColorValues), ", specified by \"--highlightcolor\" option.\nIt must contain only two value for $HighlightMode value specified using \"-m --mode\" option.\n";
1534       }
1535     }
1536     if (!$Options{highlight}) {
1537       die "Error: Specify columns to be highlighted using \"--hightlight\" option\n";
1538     }
1539     # Retrieve quartet values from "hightlight" option...
1540     my(@HighlightValueQuartets);
1541 
1542     @HighlightValueQuartets = ();
1543     @HighlightValueQuartets = split ",", $Options{highlight};
1544     if ((@HighlightValueQuartets % 4)) {
1545       die "Error: Quartets not found in values specified using \"--highlight\" option for $HighlightMode \"-m --mode\"\n";
1546     }
1547     # Process quartets...
1548     my($Index, $Label, $DataType, $Criterion, $Value);
1549 
1550     @{$OptionsInfo{SpecifiedHighlightDataFieldLabels}} = ();
1551     %{$OptionsInfo{SpecifiedHighlightDataFieldLabelsMap}} = ();
1552     %{$OptionsInfo{SpecifiedHighlightDataFieldTypesMap}} = ();
1553     %{$OptionsInfo{SpecifiedHighlightDataFieldCriteriaMap}} = ();
1554     %{$OptionsInfo{SpecifiedHighlightDataFieldValueMap}} = ();
1555 
1556     for ($Index = 0; $Index < @HighlightValueQuartets; $Index = $Index + 4) {
1557       $Label = $HighlightValueQuartets[$Index];
1558       $DataType = $HighlightValueQuartets[$Index + 1];
1559       $Criterion = $HighlightValueQuartets[$Index + 2];
1560       $Value = $HighlightValueQuartets[$Index + 3];
1561       if ($DataType !~ /^(numeric|text)$/i) {
1562         die "Error: Invalid column data type, $DataType, specified in quartet, \"$Label,$DataType,$Criterion,$Value\", using \"--hightlight\" option: Valid values: numeric or text\n";
1563       }
1564       if ($Criterion !~ /^(eq|le|ge)$/i) {
1565         die "Error: Invalid criterion value, $Criterion, specified in quartet, \"$Label,$DataType,$Criterion,$Value\", using \"--hightlight\" option: Valid values: le, ge, or eq\n";
1566       }
1567       if ($DataType =~ /^numeric$/i) {
1568         if (!IsFloat($Value)) {
1569           die "Error: Invalid criterion value, $Value, specified in quartet, \"$Label,$DataType,$Criterion,$Value\", using \"--hightlight\" option: Numeric value required for numeric data type\n";
1570         }
1571       }
1572       if (exists($OptionsInfo{SpecifiedHighlightDataFieldLabelsMap}{$Label})) {
1573         die "Error: Invalid field label value, $Label, in quartet, \"$Label,$DataType,$Criterion,$Value\", using \"--hightlight\" option: Multiple occurences of label.  \n";
1574       }
1575       push @{$OptionsInfo{SpecifiedHighlightDataFieldLabels}}, $Label;
1576       $OptionsInfo{SpecifiedHighlightDataFieldLabelsMap}{$Label} = $Label;
1577       $OptionsInfo{SpecifiedHighlightDataFieldTypesMap}{$Label} = $DataType;
1578       $OptionsInfo{SpecifiedHighlightDataFieldCriteriaMap}{$Label} = $Criterion;
1579       $OptionsInfo{SpecifiedHighlightDataFieldValueMap}{$Label} = $Value;
1580     }
1581   }
1582 }
1583 
1584 # Set up default archive and code values for a specific applet...
1585 sub SetupDefaultAppletArchiveAndCode {
1586   my($ViewerType) = @_;
1587   my($Archive, $Code, $Nothing);
1588 
1589  STRVIEWERTYPE: {
1590     if ($OptionsInfo{StrViewerType} =~ /^JME$/i) { $Archive = "JME.jar"; $Code = "JME"; last STRVIEWERTYPE; }
1591     if ($OptionsInfo{StrViewerType} =~ /^Jmol$/i) {$Archive = "JmolApplet.jar"; $Code = "JmolApplet";  last STRVIEWERTYPE; }
1592     if ($OptionsInfo{StrViewerType} =~ /^MarvinView$/i) { $Archive = "marvin.jar"; $Code = "MView"; last STRVIEWERTYPE; }
1593     $Nothing = 1;
1594   }
1595   return ($Archive, $Code);
1596 }
1597 
1598 # Retrieve information about input SD files...
1599 sub RetrieveSDFilesInfo {
1600   my($SDFile, $FileDir, $FileName, $HTMLFile, $CSSFile, $HTMLRoot, $HTMLTitle, $FileExt, $Index, $TopHTMLDir);
1601 
1602   %SDFilesInfo = ();
1603 
1604   @{$SDFilesInfo{FileOkay}} = ();
1605   @{$SDFilesInfo{CmpdCount}} = ();
1606   @{$SDFilesInfo{SpecifiedDataFieldLabels}} = ();
1607 
1608   @{$SDFilesInfo{HTMLRoot}} = ();
1609   @{$SDFilesInfo{HTMLTitle}} = ();
1610   @{$SDFilesInfo{MultipleHTMLTables}} = ();
1611 
1612   @{$SDFilesInfo{TopHTMLDir}} = ();
1613   @{$SDFilesInfo{SubHTMLDir}} = ();
1614   @{$SDFilesInfo{SubMolDir}} = ();
1615 
1616 
1617   FILELIST: for $Index (0 .. $#SDFilesList) {
1618     $SDFile = $SDFilesList[$Index];
1619 
1620     $SDFilesInfo{FileOkay}[$Index] = 0;
1621     $SDFilesInfo{CmpdCount}[$Index] = 0;
1622     $SDFilesInfo{HTMLRoot}[$Index] = "";
1623     $SDFilesInfo{HTMLTitle}[$Index] = "";
1624     $SDFilesInfo{MultipleHTMLTables}[$Index] = 0;
1625     $SDFilesInfo{TopHTMLDir}[$Index] = "";
1626     $SDFilesInfo{SubHTMLDir}[$Index] = "";
1627     $SDFilesInfo{SubMolDir}[$Index] = "";
1628 
1629     @{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]} = ();
1630 
1631     if (!(-e $SDFile)) {
1632       warn "Warning: Ignoring file $SDFile: It doesn't exist\n";
1633       next FILELIST;
1634     }
1635     if (!CheckFileType($SDFile, "sd sdf")) {
1636       warn "Warning: Ignoring file $SDFile: It's not a SD file\n";
1637       next FILELIST;
1638     }
1639     ($FileDir, $FileName, $FileExt) = ParseFileName($SDFile);
1640 
1641     if (!open SDFILE, "$SDFile") {
1642       warn "Warning: Ignoring file $SDFile: Couldn't open it: $! \n";
1643       next FILELIST;
1644     }
1645     # Count number of compounds and collect all possible data field labels...
1646     my($CmpdCount, $CmpdString, @DataFieldLabels, @CommonDataFieldLabels);
1647     $CmpdCount = 0;
1648     @DataFieldLabels = ();
1649     @CommonDataFieldLabels = ();
1650     if ($OptionsInfo{SpecifiedDataFields} =~ /^(All|Common)$/i ) {
1651       my($DataFieldLabelsRef, $CommonDataFieldLabelsRef);
1652       ($CmpdCount, $DataFieldLabelsRef, $CommonDataFieldLabelsRef) = GetAllAndCommonCmpdDataHeaderLabels(\*SDFILE);
1653       push @DataFieldLabels, @{$DataFieldLabelsRef};
1654       push @CommonDataFieldLabels, @{$CommonDataFieldLabelsRef};
1655     }
1656     else {
1657       while ($CmpdString = ReadCmpdString(\*SDFILE)) {
1658         $CmpdCount++;
1659       }
1660     }
1661     close SDFILE;
1662 
1663     $FileDir = ""; $FileName = ""; $FileExt = "";
1664     ($FileDir, $FileName, $FileExt) = ParseFileName($SDFile);
1665     $HTMLRoot = $FileName;
1666     if ($Options{root} && (@SDFilesList == 1)) {
1667       my ($RootFileDir, $RootFileName, $RootFileExt) = ParseFileName($Options{root});
1668       if ($RootFileName && $RootFileExt) {
1669         $HTMLRoot = $RootFileName;
1670       }
1671       else {
1672         $HTMLRoot = $Options{root};
1673       }
1674     }
1675     $HTMLTitle = $HTMLRoot;
1676     if ($Options{title} && (@SDFilesList == 1)) {
1677       $HTMLTitle = $Options{title};
1678     }
1679     $HTMLFile = lc($HTMLRoot) . "-html";
1680     if (!$Options{overwrite}) {
1681       if (-d $HTMLFile) {
1682         warn "Warning: Ignoring file $SDFile: The directory $HTMLFile already exists\n";
1683         next FILELIST;
1684       }
1685     }
1686     $SDFilesInfo{FileOkay}[$Index] = 1;
1687     $SDFilesInfo{CmpdCount}[$Index] = $CmpdCount;
1688     $SDFilesInfo{HTMLRoot}[$Index] = "$HTMLRoot";
1689     $SDFilesInfo{HTMLTitle}[$Index] = "$HTMLTitle";
1690     if ($OptionsInfo{MaxCmpdsPerTable} == 0 || $CmpdCount <= $OptionsInfo{MaxCmpdsPerTable}) {
1691       $SDFilesInfo{MultipleHTMLTables}[$Index] = 0;
1692     }
1693     else {
1694       $SDFilesInfo{MultipleHTMLTables}[$Index] = 1;
1695     }
1696     if ($OptionsInfo{SpecifiedDataFields} =~ /^All$/i ) {
1697       push @{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]}, @DataFieldLabels;
1698     }
1699     elsif ($OptionsInfo{SpecifiedDataFields} =~ /^Common$/i) {
1700       push @{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]}, @CommonDataFieldLabels;
1701     }
1702     else {
1703       push @{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]}, split(",", $OptionsInfo{SpecifiedDataFields});
1704     }
1705 
1706     # Setup HTML data directories paths...
1707     $TopHTMLDir = lc($SDFilesInfo{HTMLRoot}[$Index]) . "-html";
1708     $SDFilesInfo{TopHTMLDir}[$Index] = "$TopHTMLDir";
1709     $SDFilesInfo{SubHTMLDir}[$Index] = "$TopHTMLDir\/html";
1710     $SDFilesInfo{SubMolDir}[$Index] = "$TopHTMLDir\/mol";
1711   }
1712 }
1713 
1714 # Setup information...
1715 sub SetupMultipleTablesAndMiscInfo {
1716   SetupMultipleTablesInfo();
1717   SetupMiscInfo();
1718 }
1719 
1720 # Setup navigation link information for multiple tables...
1721 sub SetupMultipleTablesInfo {
1722   my($Index, $LinesPerTable);
1723 
1724   $LinesPerTable = $OptionsInfo{MaxCmpdsPerTable};
1725 
1726   @{$SDFilesInfo{TableCount}} = ();
1727   @{$SDFilesInfo{TableHTMLFiles}} = ();
1728   @{$SDFilesInfo{TableStartCmpdNum}} = ();
1729   @{$SDFilesInfo{TableEndCmpdNum}} = ();
1730 
1731   for $Index (0 .. $#SDFilesList) {
1732     $SDFilesInfo{TableCount}[$Index] = 1;
1733     @{$SDFilesInfo{TableHTMLFiles}[$Index]} = ();
1734     @{$SDFilesInfo{TableStartCmpdNum}[$Index]} = ();
1735     @{$SDFilesInfo{TableEndCmpdNum}[$Index]} = ();
1736 
1737     if ($SDFilesInfo{FileOkay}[$Index]) {
1738       if ($SDFilesInfo{MultipleHTMLTables}[$Index]) {
1739         my($TableIndex, $TotalLines, $TableCount, $TableStartLineNum, $TableEndLineNum, $Name);
1740 
1741         $TotalLines = $SDFilesInfo{CmpdCount}[$Index];
1742         $TableCount = ($TotalLines % $LinesPerTable) ? (int($TotalLines/$LinesPerTable) + 1) : ($TotalLines/$LinesPerTable);
1743         $SDFilesInfo{TableCount}[$Index] = $TableCount;
1744         for $TableIndex (1 .. $TableCount) {
1745           $TableStartLineNum = ($TableIndex - 1) * $LinesPerTable + 1;
1746           $TableEndLineNum = ($TableIndex == $TableCount) ? $TotalLines : ($TableIndex * $LinesPerTable);
1747           push @{$SDFilesInfo{TableStartCmpdNum}[$Index]}, $TableStartLineNum;
1748           push @{$SDFilesInfo{TableEndCmpdNum}[$Index]}, $TableEndLineNum;
1749 
1750           # Setup HTML file names for all the tables...
1751           $Name = "Cmpd" . "$TableStartLineNum" . "To" . "$TableEndLineNum";
1752           if ($TableIndex == 1) {
1753             $Name = "";
1754           }
1755           $Name = $SDFilesInfo{HTMLRoot}[$Index] . $Name . ".html";
1756           push @{$SDFilesInfo{TableHTMLFiles}[$Index]}, $Name;
1757         }
1758         #print "$SDFilesList[$Index]: $TableCount -  @{$SDFilesInfo{TableStartCmpdNum}[$Index]} - @{$SDFilesInfo{TableEndCmpdNum}[$Index]} -  @{$SDFilesInfo{TableHTMLFiles}[$Index]}\n";
1759       }
1760     }
1761   }
1762 }
1763 
1764 # Setup HTML tags and other information...
1765 sub SetupMiscInfo {
1766   $SDFilesInfo{RowHeaderTags} = "";
1767   $SDFilesInfo{RowEndTags} = "";
1768   $SDFilesInfo{BgFilledOddRowHeaderTags} = "";
1769   $SDFilesInfo{BgFilledEvenRowHeaderTags} = "";
1770   $SDFilesInfo{TableRowHeaderTags} = "";
1771 
1772   $SDFilesInfo{RowHeaderTags} = SetupHTMLTableRowHeader($OptionsInfo{RowHAlignment}, "", $OptionsInfo{RowVAlignment});
1773   $SDFilesInfo{RowEndTags} = SetupHTMLTableRowEnd();
1774 
1775   if ($OptionsInfo{ShadeRowsStatus}) {
1776     $SDFilesInfo{BgFilledOddRowHeaderTags} = SetupHTMLTableRowHeader($OptionsInfo{RowHAlignment}, $OptionsInfo{OddRowsShadeColor}, $OptionsInfo{RowVAlignment});
1777     $SDFilesInfo{BgFilledEvenRowHeaderTags} = SetupHTMLTableRowHeader($OptionsInfo{RowHAlignment}, $OptionsInfo{EvenRowsShadeColor}, $OptionsInfo{RowVAlignment});
1778   }
1779 
1780   $SDFilesInfo{TableRowHeaderTags} = SetupHTMLTableRowHeader($OptionsInfo{TableHeaderRowHAlignment}, $OptionsInfo{TableHeaderRowColor}, $OptionsInfo{TableHeaderRowVAlignment});
1781 
1782   $SDFilesInfo{MolEndTag} = "M  END";
1783   $SDFilesInfo{White} = qq(#ffffff);
1784 }
1785 
1786 # Setup various data directories to hold HTML and other related files...
1787 sub SetupDataDirs {
1788   my($Index) = @_;
1789   my($TopHTMLDir, $SubHTMLDir, $SubMolDir, $CreateTopHTMLDir, $CreateSubHTMLDir, $CreateSubMolDir);
1790 
1791   $TopHTMLDir = $SDFilesInfo{TopHTMLDir}[$Index];
1792   $SubHTMLDir = $SDFilesInfo{SubHTMLDir}[$Index];
1793   $SubMolDir = $SDFilesInfo{SubMolDir}[$Index];
1794 
1795   # Clean up existing directories...
1796   if (-d $TopHTMLDir) {
1797     unlink "<$TopHTMLDir/*.html>";
1798     unlink "<$TopHTMLDir/*.css>";
1799   }
1800   if (-d $SubHTMLDir) {
1801     unlink "<$SubHTMLDir/*.html>";
1802   }
1803   if (-d $SubMolDir) {
1804     unlink "<$SubMolDir/*.mol>";
1805   }
1806 
1807   # What directories need to be created...
1808   $CreateTopHTMLDir = (-d $TopHTMLDir) ? 0 : 1;
1809   $CreateSubHTMLDir = (-d $SubHTMLDir) ? 0 : 1;
1810   $CreateSubMolDir = 0;
1811   if ($OptionsInfo{StrViewerType} =~ /^(Jmol|Chime|Chem3DActiveX|ChemDrawActiveX|ChemDrawPlugIn|ViewerActiveX)$/i) {
1812     $CreateSubMolDir = (-d $SubMolDir) ? 0 : 1;
1813   }
1814 
1815   # Create appropriate directories...
1816   if ($CreateTopHTMLDir) {
1817     mkdir $TopHTMLDir or die "Couldn't mkdir $TopHTMLDir: $! \n";
1818   }
1819   if ($CreateSubHTMLDir) {
1820     mkdir $SubHTMLDir or die "Error: Couldn't mkdir $SubHTMLDir: $! \n";
1821   }
1822   else {
1823     unlink <$SubHTMLDir/*.html>;
1824   }
1825   if ($CreateSubMolDir) {
1826     mkdir $SubMolDir or die "Error: Couldn't mkdir $SubMolDir: $! \n";
1827   }
1828   return ($TopHTMLDir, $SubHTMLDir, $SubMolDir);
1829 }
1830 
1831 # Setup script usage  and retrieve command line arguments specified using various options...
1832 sub SetupScriptUsage {
1833 
1834   # Retrieve all the options...
1835   %Options = ();
1836 
1837   $Options{mode} = "shade";
1838   $Options{highlightstyle} = "background";
1839 
1840   $Options{cellpadding} = 2;
1841   $Options{cellspacing} = 1;
1842 
1843   $Options{displaylinks} = "both";
1844   $Options{displaylinksinfo} = "both";
1845   $Options{stylesheet} = "new";
1846 
1847   $Options{structure} = "display";
1848   $Options{strlinktype} = "href";
1849   $Options{strlinkmode} = "plain";
1850   $Options{strlinknavigation} = "yes";
1851   $Options{strlinktitledisplay} = "no";
1852 
1853   $Options{strviewertype} = "Jmol";
1854   $Options{strviewerembed} = "direct";
1855 
1856   $Options{titledisplay} = "yes";
1857 
1858   if (!GetOptions(\%Options, "align|a=s", "border|b=i", "cellpadding=i", "cellspacing=i", "cmpddatafield|c=s", "datafields=s", "footer=s", "displaylinks|d=s", "displaylinksinfo=s", "help|h", "headeralign=s", "headercolor=s", "highlight=s", "highlightcolor=s", "highlightstyle=s", "mode|m=s", "numcmpds|n=i", "overwrite|o", "root|r=s", "shadecolor=s", "stylesheet=s", "stylesheetname=s", "structure|s=s", "strlinkmode=s", "strlinknavigation=s", "strlinkshadecolor=s", "strlinktitle=s", "strlinktitledisplay=s", "strlinktype=s", "strviewertype=s", "strviewerconfig=s", "strviewerparams=s", "strviewerembed=s",  "strviewerjsfile=s", "strtablesize=s", "title|t=s", "titledisplay=s", "workingdir|w=s")) {
1859     die "\nTo get a list of valid options and their values, use \"$ScriptName -h\" or\n\"perl -S $ScriptName -h\" command and try again...\n";
1860   }
1861 
1862   if ($Options{workingdir}) {
1863     if (! -d $Options{workingdir}) {
1864       die "Error: The value specified, $Options{workingdir}, for option \"-w --workingdir\" is not a directory name.\n";
1865     }
1866     chdir $Options{workingdir} or die "Error: Couldn't chdir $Options{workingdir}: $! \n";
1867   }
1868   if ($Options{displaylinks} !~ /^(top|bottom|both)$/i) {
1869     die "Error: The value specified, $Options{displaylinks}, for option \"-d --displaylinks\" is not valid. Allowed values: top, bottom, or both\n";
1870   }
1871   if ($Options{displaylinksinfo} !~ /^(compound|table|both)$/i) {
1872     die "Error: The value specified, $Options{displaylinksinfo}, for option \"--displaylinksinfo\" is not valid. Allowed values: compound, table, or both\n";
1873   }
1874   if ($Options{highlightstyle} !~ /^(background|text)$/i) {
1875     die "Error: The value specified, $Options{highlightstyle}, for option \"--highlightstyle\" is not valid. Allowed values: background or text\n";
1876   }
1877   if ($Options{mode} !~ /^(plain|shade|highlight|shadedhighlight|structuresonly|shadedstructuresonly)$/i) {
1878     die "Error: The value specified, $Options{mode}, for option \"-m --mode\" is not valid. Allowed values: plain, shade, hightlight, shadedhighlight, structuresonly, or shadedstructuresonly\n";
1879   }
1880   if ($Options{stylesheet} !~ /^(old|new|none)$/i) {
1881     die "Error: The value specified, $Options{stylesheet}, for option \"-s --stylesheet\" is not valid. Allowed values: old, new, or none\n";
1882   }
1883   if ($Options{structure} !~ /^(display|link)$/i) {
1884     die "Error: The value specified, $Options{structure}, for option \"-s --structure\" is not valid. Allowed values: display or link\n";
1885   }
1886   if ($Options{strlinkmode} !~ /^(plain|shade)$/i) {
1887     die "Error: The value specified, $Options{strlinkmode}, for option \"--strlinkmode\" is not valid. Allowed values: plain or shade\n";
1888   }
1889   if ($Options{strlinktype} !~ /^(href|button)$/i) {
1890     die "Error: The value specified, $Options{strlinktype}, for option \"--strlinktype\" is not valid. Allowed values: href or button\n";
1891   }
1892   if ($Options{strlinknavigation} !~ /^(yes|no)$/i) {
1893     die "Error: The value specified, $Options{strlinknavigation}, for option \"--strlinknavigation\" is not valid. Allowed values: yes or no\n";
1894   }
1895   if ($Options{strlinktitledisplay} !~ /^(yes|no)$/i) {
1896     die "Error: The value specified, $Options{strlinktitledisplay}, for option \"--strlinktitledisplay\" is not valid. Allowed values: yes or no\n";
1897   }
1898   if ($Options{strviewertype} !~ /^(JME|Jmol|Chime|MarvinView|ChemDrawPlugIn|Chem3DActiveX|ChemDrawActiveX|ViewerActiveX)$/i) {
1899     die "Error: The value specified, $Options{strviewertype}, for option \"--strviewertype\" is not valid. Allowed values: Chem3DActiveX, ChemDrawActiveX, ChemDrawPlugIn, Chime, JME, Jmol, MarvinView, or ViewerActiveX.\n";
1900   }
1901   if ($Options{strviewerembed} !~ /^(direct|javascript)$/i) {
1902     die "Error: The value specified, $Options{strviewerembed},  for option \"--strviewerembed\" is not valid. Allowed values: direct or javascript \n";
1903   }
1904   if (exists $Options{numcmpds} && $Options{numcmpds} < 0) {
1905     die "Error: The value specified, $Options{numcmpds},  for option \"-n --numcmpds\" is not valid. Allowed values: >= 0 \n";
1906   }
1907   if ($Options{titledisplay} !~ /^(yes|no)$/i) {
1908     die "Error: The value specified, $Options{titledisplay}, for option \"--titledisplay\" is not valid. Allowed values: yes or no\n";
1909   }
1910   if (exists($Options{border})) {
1911     if ($Options{border} < 0) {
1912       die "Error: The value specified, $Options{border},  for option \"--border\" is not valid. Allowed values: >= 0 \n";
1913     }
1914   }
1915   if ($Options{cellpadding} < 0) {
1916     die "Error: The value specified, $Options{cellpadding},  for option \"--cellpadding\" is not valid. Allowed values: >= 0 \n";
1917   }
1918   if ($Options{cellspacing} < 0) {
1919     die "Error: The value specified, $Options{cellspacing},  for option \"--cellspacing\" is not valid. Allowed values: >= 0 \n";
1920   }
1921 }
1922