MayaChemTools

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