MayaChemTools

   1 #!/bin/perl -w
   2 #
   3 # $RCSfile: SDFilesToHTML.pl,v $
   4 # $Date: 2008/04/07 02:30:40 $
   5 # $Revision: 1.35 $
   6 #
   7 # Author: Manish Sud <msud@san.rr.com>
   8 #
   9 # Copyright (C) 2004-2008 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 5.006;
  30 use strict;
  31 use FindBin; use lib "$FindBin::Bin/../lib";
  32 use Getopt::Long;
  33 use File::Basename;
  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($ShadeRowsStatus, $HighlightStatus, $OddRowsShadeColor, $EvenRowsShadeColor, $StrWidth, $StrHeight, $SpecifiedDataFields, $StrLinkShadeColor, $StrLinkNavigation, $StrLinkTitle, $StrLinkTitleDisplay, $StrLinkWidth, $StrLinkHeight, $StrLinkBgColorSpecified, $SettingUpCmpdSummaryPage, $ValueOkColor, $ValueNotOkColor, $TableHeaderRowColor, $RowVAlignment, $RowHAlignment, $TableHeaderRowHAlignment, $TableHeaderRowVAlignment, $TableBorder, $TableCellPadding, $TableCellSpacing, $FooterMsg, $DisplayStructure, $StrViewerType, $StrViewerCodeBase, %StrViewerParams, $StrViewerJSFileRef, $StrBgColorSpecified, $NavLinksAtTop, $NavLinksAtBottom, $NavLinksTableInfo, $NavLinksCmpdInfo, $StructuresOnlyMode, $CmpdDataField, $CmpdDataFieldLabel, $CmpdDataFieldPosition, $CmpdDataFieldAlignment, $StrTableRows, $StrTableCols, $MaxCmpdsPerTable, $TitleDisplay, @SpecifiedHighlightDataFieldLabels, %SpecifiedHighlightDataFieldLabelsMap, %SpecifiedHighlightDataFieldTypesMap, %SpecifiedHighlightDataFieldCriteriaMap, %SpecifiedHighlightDataFieldValueMap);
  64 ProcessOptions();
  65 
  66 # Collect information about SD files...
  67 print "Checking input SD file(s)...\n";
  68 my(@SDFilesOkay, @SDFilesCmpdCount, @SDFilesSpecifiedDataFieldLabels, @SDFilesHTMLRoot, @SDFilesHTMLTitle, @SDFilesMultipleHTMLTables, @SDFilesTopHTMLDir, @SDFilesSubHTMLDir, @SDFilesSubMolDir);
  69 RetrieveSDFilesInfo();
  70 
  71 # Setup navigation link information for multiple tables...
  72 my(@SDFilesTableCount, @SDFilesTableHTMLFiles, @SDFilesTableStartCmpdNum, @SDFilesTableEndCmpdNum);
  73 SetupMultipleTablesInfo();
  74 
  75 # Setup various miscellaneous value...
  76 my($Index, $SDFile, $RowHeaderTags, $RowEndTags, $BgFilledOddRowHeaderTags, $BgFilledEvenRowHeaderTags, $TableRowHeaderTags, $MolEndTag, $White);
  77 $RowHeaderTags = ""; $RowEndTags = "";  $BgFilledOddRowHeaderTags = ""; $BgFilledEvenRowHeaderTags = ""; $TableRowHeaderTags = "";
  78 $RowHeaderTags = SetupHTMLTableRowHeader($RowHAlignment, "", $RowVAlignment);
  79 $RowEndTags = SetupHTMLTableRowEnd();
  80 if ($ShadeRowsStatus) {
  81   $BgFilledOddRowHeaderTags = SetupHTMLTableRowHeader($RowHAlignment, $OddRowsShadeColor, $RowVAlignment);
  82   $BgFilledEvenRowHeaderTags = SetupHTMLTableRowHeader($RowHAlignment, $EvenRowsShadeColor, $RowVAlignment);
  83 }
  84 $TableRowHeaderTags = SetupHTMLTableRowHeader($TableHeaderRowHAlignment, $TableHeaderRowColor, $TableHeaderRowVAlignment);
  85 $MolEndTag = "M  END";
  86 $White = qq(#ffffff);
  87 
  88 # Start generating HTML tables...
  89 if (@SDFilesList > 1) {
  90   print "Processing SD files...\n";
  91 }
  92 for $Index (0 .. $#SDFilesList) {
  93   if ($SDFilesOkay[$Index]) {
  94     $SDFile = $SDFilesList[$Index];
  95     if (@SDFilesList > 1) {
  96       print "\nProcessing file $SDFile...\n";
  97     }
  98     else {
  99       print "Processing file $SDFile...\n"
 100     }
 101     if ($SDFilesMultipleHTMLTables[$Index]) {
 102       GenerateMultipleHTMLTables($Index);
 103     }
 104     else {
 105       GenerateOneHTMLTable($Index);
 106     }
 107   }
 108 }
 109 
 110 print "$ScriptName:Done...\n\n";
 111 
 112 $EndTime = new Benchmark;
 113 $TotalTime = timediff ($EndTime, $StartTime);
 114 print "Total time: ", timestr($TotalTime), "\n";
 115 
 116 ###############################################################################
 117 
 118 sub GenerateOneHTMLTable {
 119   my($Index) = @_;
 120   my($TopHTMLDir, $HTMLFile, $StartCmpdNum, $EndCmpdNum, $CSSFile, $CSSRef, $CSSFilePath, $TableNum);
 121 
 122   $HTMLFile = $SDFilesHTMLRoot[$Index] . ".html";
 123   $SDFile = $SDFilesList[$Index];
 124 
 125   # Setup data directories...
 126   ($TopHTMLDir) = SetupDataDirs($Index);
 127 
 128   # Setup stylesheet file...
 129   $CSSRef = "";
 130   if ($Options{stylesheet} =~ /^new$/i) {
 131     $CSSFile = $SDFilesHTMLRoot[$Index] . ".css"; $CSSRef = ".\/" . "$CSSFile";
 132     $CSSFilePath = "$TopHTMLDir" . "\/" . $CSSFile;
 133     GenerateStyleSheetFile($CSSFilePath);
 134   }
 135   elsif ($Options{stylesheet} =~ /^old$/i) {
 136     $CSSRef = $Options{stylesheetname};
 137   }
 138 
 139   # Set HTML file location...
 140   $HTMLFile = "$TopHTMLDir" . "\/" . $HTMLFile;
 141 
 142   print "Generating HTML file $HTMLFile...\n";
 143   open HTMLFILE, ">$HTMLFile" or die "Error: Can't open $HTMLFile: $! \n";
 144   open SDFILE, "$SDFile" or die "Error: Can't open $SDFile: $! \n";
 145 
 146   # Write out HTML page header...
 147   print HTMLFILE SetupHTMLPageHeader($SDFilesHTMLTitle[$Index], $CSSRef, $StrViewerJSFileRef);
 148 
 149   if ($StrViewerJSFileRef) {
 150     print HTMLFILE SetupStrViewerJSInitCmd($StrViewerType, $StrViewerCodeBase);
 151   }
 152 
 153   # Setup page title...
 154   if ($TitleDisplay) {
 155     print HTMLFILE SetupHTMLPageTitle($SDFilesHTMLTitle[$Index]);
 156   }
 157   else {
 158     print HTMLFILE SetupHTMLEmptyLines(1);
 159   }
 160 
 161   # Start the table...
 162   print HTMLFILE SetupHTMLAlignmentBegin("center");
 163   print HTMLFILE SetupHTMLTableHeader($TableBorder, $TableCellPadding, $TableCellSpacing);
 164 
 165   # Generate table rows...
 166   $StartCmpdNum = 1;
 167   $EndCmpdNum = $SDFilesCmpdCount[$Index];
 168   $TableNum = 1;
 169   GenerateTableRows($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, \*SDFILE, \*HTMLFILE);
 170 
 171   # Finish up the table...
 172   print HTMLFILE SetupHTMLTableEnd();
 173   print HTMLFILE SetupHTMLAlignmentEnd("center");
 174 
 175   # Write out HTML page end...
 176   print HTMLFILE SetupHTMLPageEnd($FooterMsg);
 177 
 178   close HTMLFILE;
 179   close SDFILE;
 180 }
 181 
 182 # Generate multiple tables...
 183 sub GenerateMultipleHTMLTables {
 184   my($Index) = @_;
 185   my($TopHTMLDir, $SubHTMLDir, $SDFile, $HTMLFile, $TableNum, $TableCount, $TableIndex, $TableStartCmpdNum, $TableEndCmpdNum, $PrintMsg, $CSSFile, $CSSRef, $CSSFilePath, $NewStyleSheet);
 186 
 187   # Open SD file...
 188   $SDFile = $SDFilesList[$Index];
 189   open SDFILE, "$SDFile" or die "Error: Can't open $SDFile: $! \n";
 190 
 191   # Set up data directories to hold various html files...
 192   ($TopHTMLDir, $SubHTMLDir) = SetupDataDirs($Index);
 193 
 194   # Create stylesheet file...
 195   $CSSRef = "";
 196   $NewStyleSheet = 0;
 197   if ($Options{stylesheet} =~ /^new$/i) {
 198     $NewStyleSheet = 1;
 199     $CSSFile = $SDFilesHTMLRoot[$Index] . ".css";
 200     $CSSFilePath = "$TopHTMLDir" . "\/" . $CSSFile;
 201     GenerateStyleSheetFile($CSSFilePath);
 202   }
 203   elsif ($Options{stylesheet} =~ /^old$/i) {
 204     $CSSRef = $Options{stylesheetname};
 205   }
 206 
 207   $PrintMsg = 1;
 208   # Generate HTML files for all the tables...
 209   $TableCount = $SDFilesTableCount[$Index];
 210   for $TableNum (1 .. $TableCount) {
 211     $TableIndex = $TableNum - 1;
 212     $HTMLFile = ${$SDFilesTableHTMLFiles[$Index]}[$TableIndex];
 213     $TableStartCmpdNum = ${$SDFilesTableStartCmpdNum[$Index]}[$TableIndex];
 214     $TableEndCmpdNum = ${$SDFilesTableEndCmpdNum[$Index]}[$TableIndex];
 215 
 216     # Setup file name...
 217     if ($TableNum == 1) {
 218       $HTMLFile = "$TopHTMLDir" . "\/" . $HTMLFile;
 219       print "Generating HTML file $HTMLFile...\n";
 220     }
 221     else {
 222       $HTMLFile = "$SubHTMLDir" . "\/" . $HTMLFile;
 223       if ($PrintMsg) {
 224 	$PrintMsg = 0;
 225 	if ($TableCount == 2) {
 226 	  print "Generating HTML file $HTMLFile...\n";
 227 	}
 228 	else {
 229 	  print "Generating ", ($TableCount - 1), " other HTML files: $SubHTMLDir\/$SDFilesHTMLRoot[$Index]\*.html...\n";
 230 	}
 231       }
 232     }
 233     # Setup stylesheet reference...
 234     if ($NewStyleSheet) {
 235       $CSSRef = ($TableNum == 1) ? ".\/" : "..\/";
 236       $CSSRef .= $CSSFile;
 237     }
 238 
 239     open HTMLFILE, ">$HTMLFile" or die "Error: Can't open $HTMLFile: $! \n";
 240     # Write out HTML page header...
 241     print HTMLFILE SetupHTMLPageHeader($SDFilesHTMLTitle[$Index], $CSSRef, $StrViewerJSFileRef);
 242 
 243     if ($StrViewerJSFileRef) {
 244       print HTMLFILE SetupStrViewerJSInitCmd($StrViewerType, $StrViewerCodeBase);
 245     }
 246 
 247     # Set up the navigation links for this table...
 248     if ($NavLinksAtTop) {
 249       WriteNavigationLinks($Index, $TableNum, \*HTMLFILE);
 250     }
 251     # Setup page title...
 252     if ($TitleDisplay) {
 253       print HTMLFILE SetupHTMLPageTitle($SDFilesHTMLTitle[$Index]);
 254     }
 255     else {
 256       print HTMLFILE SetupHTMLEmptyLines(1);
 257     }
 258 
 259     # Start the table...
 260     print HTMLFILE SetupHTMLAlignmentBegin("center");
 261     print HTMLFILE SetupHTMLTableHeader($TableBorder, $TableCellPadding, $TableCellSpacing);
 262 
 263     # Generate table content...
 264     GenerateTableRows($Index, $TableNum, $TableStartCmpdNum, $TableEndCmpdNum, \*SDFILE, \*HTMLFILE);
 265 
 266     # Finish up the table...
 267     print HTMLFILE SetupHTMLTableEnd();
 268     print HTMLFILE SetupHTMLAlignmentEnd("center");
 269 
 270     # Set up the navigation links for this table...
 271     if ($NavLinksAtBottom) {
 272       print HTMLFILE SetupHTMLEmptyLines(1);
 273       WriteNavigationLinks($Index, $TableNum, \*HTMLFILE);
 274     }
 275 
 276     # Write out HTML page end...
 277     print HTMLFILE SetupHTMLPageEnd($FooterMsg);
 278     close HTMLFILE;
 279   }
 280   close SDFILE;
 281 
 282 }
 283 
 284 # Generate table content...
 285 sub GenerateTableRows {
 286   my($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef) = @_;
 287 
 288   if ($StructuresOnlyMode) {
 289     WriteRowStructures($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef);
 290   }
 291   else {
 292     WriteColLabels($Index, $SDFileRef, $HTMLFileRef);
 293     WriteRowValues($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef);
 294   }
 295 }
 296 
 297 # Create stylesheet file...
 298 sub GenerateStyleSheetFile {
 299   my($CSSFile) = @_;
 300     print "Generating stylesheet file $CSSFile...\n";
 301     open CSSFILE, ">$CSSFile" or die "Error: Can't open $CSSFile: $! \n";
 302     print CSSFILE SetupHTMLStyleSheetTags();
 303     close CSSFILE;
 304 }
 305 
 306 # Write out table header using column labels...
 307 sub WriteColLabels {
 308   my($Index, $SDFileRef, $HTMLFileRef) = @_;
 309 
 310   my(@ColLabels, $Label);
 311   print $HTMLFileRef $TableRowHeaderTags;
 312 
 313   # Write out structure label...
 314   $Label = "Structure";
 315   print $HTMLFileRef SetupHTMLTableRowHeaderValue($Label);
 316 
 317   # Write out field values..
 318   @ColLabels = @{$SDFilesSpecifiedDataFieldLabels[$Index]};
 319   for $Label (@ColLabels) {
 320     print $HTMLFileRef SetupHTMLTableRowHeaderValue($Label);
 321   }
 322   print $HTMLFileRef $RowEndTags;
 323 }
 324 
 325 # Write out the rows value...
 326 sub WriteRowValues {
 327   my($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef) = @_;
 328   my($BackgroundColor, $FontColor, $RowNum, $CmpdNum, $CmpdString, @CmpdLines, $Label, %DataFieldValues, $Value);
 329 
 330   $RowNum = 0;
 331   for $CmpdNum ($StartCmpdNum .. $EndCmpdNum) {
 332     $RowNum++;
 333     $CmpdString = ReadCmpdString($SDFileRef);
 334     if ($ShadeRowsStatus) {
 335       print $HTMLFileRef ($RowNum % 2) ? $BgFilledOddRowHeaderTags : $BgFilledEvenRowHeaderTags;
 336     }
 337     else {
 338       print $HTMLFileRef $RowHeaderTags;
 339     }
 340     @CmpdLines = split "\n", $CmpdString;
 341     %DataFieldValues = GetCmpdDataHeaderLabelsAndValues(\@CmpdLines);
 342 
 343     # Setup structure column...
 344     SetupStructureColumn($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 345     # Write out field values..
 346     for $Label (@{$SDFilesSpecifiedDataFieldLabels[$Index]}) {
 347       $Value = (IsNotEmpty($DataFieldValues{$Label})) ? $DataFieldValues{$Label} : "";
 348       $BackgroundColor = ""; $FontColor = "";
 349       if ($HighlightStatus) {
 350 	if (exists($SpecifiedHighlightDataFieldLabelsMap{$Label})) {
 351 	  ($BackgroundColor, $FontColor) = GetValueHighlightColors($Label, $Value);
 352 	}
 353       }
 354       print $HTMLFileRef SetupHTMLTableRowDataValue($Value, $BackgroundColor, $FontColor);
 355     }
 356     print $HTMLFileRef $RowEndTags;
 357   }
 358 }
 359 
 360 # Write only structures...
 361 sub WriteRowStructures {
 362   my($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef) = @_;
 363   my($CmpdNum, $CmpdString, $StartRowFlag, $ColNum, $RowNum, $RowBgColor, $RowStartTags, $ColumnHeaderTags, $ColumnEndTags, $CmpdDataFieldValue, $CmpdHTMLFileRef, $Value);
 364 
 365   $StartRowFlag = 1; $ColNum = 0; $RowNum = 0;
 366   $ColumnHeaderTags = SetupHTMLTableColumnHeader();
 367   $ColumnEndTags = SetupHTMLTableColumnEnd();
 368 
 369   if ($StructuresOnlyMode && !$TableBorder && ($OddRowsShadeColor =~ /^(#ffffff|white)$/i)) {
 370     print $HTMLFileRef SetupHTMLTableRowHeader($RowHAlignment, $TableHeaderRowColor, $RowVAlignment);
 371     $Value = SetupHTMLTableRowDataValue("");
 372     print $HTMLFileRef InsertHTMLTags($Value, "colspan", "$StrTableCols");
 373     print $HTMLFileRef $RowEndTags;
 374   }
 375 
 376   for $CmpdNum ($StartCmpdNum .. $EndCmpdNum) {
 377     $CmpdString = ReadCmpdString($SDFileRef);
 378     if ($StartRowFlag) {
 379       $StartRowFlag = 0;
 380       $RowNum++;
 381       if ($ShadeRowsStatus) {
 382 	print $HTMLFileRef ($RowNum % 2) ? $BgFilledOddRowHeaderTags : $BgFilledEvenRowHeaderTags;
 383       }
 384       else {
 385 	print $HTMLFileRef $RowHeaderTags;
 386       }
 387     }
 388     $ColNum++;
 389 
 390     $CmpdDataFieldValue = "";
 391     if ($CmpdDataField) {
 392       my(@CmpdLines, %DataFieldValues);
 393       @CmpdLines = split "\n", $CmpdString;
 394       %DataFieldValues = GetCmpdDataHeaderLabelsAndValues(\@CmpdLines);
 395       if (exists($DataFieldValues{$CmpdDataField}) && length($DataFieldValues{$CmpdDataField})) {
 396 	$CmpdDataFieldValue = $DataFieldValues{$CmpdDataField};
 397 	if ($CmpdDataFieldLabel =~ /^yes$/i) {
 398 	  $CmpdDataFieldValue = "${CmpdDataField}: ${CmpdDataFieldValue}";
 399 	}
 400 	# Make sure it's not to looong...
 401 	if (length($CmpdDataFieldValue) > 30) {
 402 	  $CmpdDataFieldValue = substr($CmpdDataFieldValue, 0, 30) . "...";
 403 	}
 404       }
 405     }
 406     if ($CmpdDataFieldValue) {
 407       $RowBgColor = "";
 408       if ($ShadeRowsStatus) {
 409 	$RowBgColor = ($RowNum % 2) ? $OddRowsShadeColor : $EvenRowsShadeColor;
 410       }
 411       $RowStartTags = SetupHTMLTableRowHeader($CmpdDataFieldAlignment, $RowBgColor, "middle");
 412       # Start  a new table in current column...
 413       print $HTMLFileRef $ColumnHeaderTags;
 414       print $HTMLFileRef SetupHTMLAlignmentBegin("center");
 415       print $HTMLFileRef SetupHTMLTableHeader(0, 0, 0);
 416 
 417       if ($CmpdDataFieldPosition =~ /^top$/i ) {
 418 	# Add an empty row...
 419 	print $HTMLFileRef $RowStartTags;
 420 	print $HTMLFileRef SetupHTMLTableRowDataValue("");
 421 	print $HTMLFileRef $RowEndTags;
 422 
 423 	# Display the label value...
 424 	print $HTMLFileRef $RowStartTags;
 425 	$CmpdHTMLFileRef = SetupCompoundSummaryFileAndLink($Index, $TableNum, $CmpdString, $CmpdNum);
 426 	$Value = SetupHTMLHRef("$CmpdDataFieldValue", $CmpdHTMLFileRef, "Compound Summary");
 427 	print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
 428 	print $HTMLFileRef $RowEndTags;
 429       }
 430       # Display the structure...
 431       print $HTMLFileRef SetupHTMLTableRowHeader("center", $RowBgColor, "middle");
 432       SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 433       print $HTMLFileRef $RowEndTags;
 434 
 435       if ($CmpdDataFieldPosition =~ /^bottom$/i ) {
 436 	# Display the label value...
 437 	print $HTMLFileRef $RowStartTags;
 438 	$CmpdHTMLFileRef = SetupCompoundSummaryFileAndLink($Index, $TableNum, $CmpdString, $CmpdNum);
 439 	$Value = SetupHTMLHRef("$CmpdDataFieldValue", $CmpdHTMLFileRef, "Compound Summary");
 440 	print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
 441 	print $HTMLFileRef $RowEndTags;
 442 
 443 	# Add an empty row...
 444 	print $HTMLFileRef $RowStartTags;
 445 	print $HTMLFileRef SetupHTMLTableRowDataValue("");
 446 	print $HTMLFileRef $RowEndTags;
 447       }
 448 
 449       print $HTMLFileRef SetupHTMLTableEnd();
 450       print $HTMLFileRef SetupHTMLAlignmentEnd("center");
 451       print $HTMLFileRef $ColumnEndTags;
 452     }
 453     else {
 454       SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 455     }
 456 
 457     if ($ColNum == $StrTableCols) {
 458       # Finish up the current row and get ready for starting a new row...
 459       print $HTMLFileRef $RowEndTags;
 460       $ColNum = 0;
 461       $StartRowFlag = 1;
 462     }
 463   }
 464   if (!$StartRowFlag) {
 465     # Finish up an existing row...
 466     my($ColIndex, $Value);
 467     $Value = "";
 468     for $ColIndex ($ColNum .. ($StrTableCols - 1) ) {
 469       print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
 470     }
 471     print $HTMLFileRef $RowEndTags;
 472   }
 473 }
 474 
 475 # Setup structure column...
 476 sub SetupStructureColumn {
 477   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 478 
 479   if ($DisplayStructure) {
 480     SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 481   }
 482   else {
 483     SetupStructureLink($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 484   }
 485 }
 486 
 487 # Setup structure display for compound summary page...
 488 sub SetupStructureDisplayForCmpdSummaryPage {
 489   my($Index, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 490   my($TableNum, $RowNum);
 491 
 492   # Use table num 0 to force usage of "../mol" prefix for all MOL file references. Row num
 493   # doesn't matter...
 494   $TableNum = 0;
 495   $RowNum = 1;
 496 
 497   $SettingUpCmpdSummaryPage = 1;
 498 
 499   # Setup size and bgcolor parameters for linking structures...
 500   $StrViewerParams{width} = $StrLinkWidth;
 501   $StrViewerParams{height} = $StrLinkHeight;
 502   $StrViewerParams{bgcolor} = $StrLinkBgColorSpecified;
 503 
 504   SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
 505 
 506   # Reset size and bgcolor parameters back to displaying structures in tables...
 507   $StrViewerParams{width} = $StrWidth;
 508   $StrViewerParams{height} = $StrHeight;
 509   $StrViewerParams{bgcolor} = $StrBgColorSpecified ? $StrBgColorSpecified : "";
 510 
 511   $SettingUpCmpdSummaryPage = 0;
 512 }
 513 
 514 
 515 # Setup structure column display...
 516 sub SetupStructureDisplay {
 517   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 518   my($Nothing);
 519 
 520  STRVIEWERTYPE: {
 521     if ($StrViewerType =~ /^JME$/i) { SetupJMEDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 522     if ($StrViewerType =~ /^Jmol$/i) { SetupJmolDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 523     if ($StrViewerType =~ /^Chime$/i) { SetupChimeDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 524     if ($StrViewerType =~ /^(Chem3DActiveX|ChemDrawActiveX|ChemDrawPlugIn)$/i) { SetupCambridgeSoftDisplay($StrViewerType, $Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 525     if ($StrViewerType =~ /^MarvinView$/i) { SetupMarvinDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 526     if ($StrViewerType =~ /^ViewerActiveX$/i) { SetupViewerAccelrysActiveXDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
 527     $Nothing = 1;
 528   }
 529 }
 530 
 531 # Setup JME display...
 532 sub SetupJMEDisplay {
 533   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 534   my($MolString, $AppletBGColor, $Value, $ValueTag, $AppletName);
 535 
 536   $Value = "";
 537   ($MolString) = split "$MolEndTag", $CmpdString;
 538   if (IsNotEmpty($MolString)) {
 539     $AppletBGColor = SetupStructureBGColor($RowNum);
 540     $MolString .= "$MolEndTag";
 541 
 542     # JME viewer doesn't appear to support "bgcolor" param. So, always use white background for
 543     # structure cell...
 544     $AppletName = "JME" . $CmpdNum;
 545     $StrViewerParams{name} = $AppletName;
 546     if (!$SettingUpCmpdSummaryPage) {
 547       if (!$StrBgColorSpecified) {
 548 	$StrViewerParams{bgcolor} = $AppletBGColor;
 549       }
 550     }
 551     $Value = SetupStrViewerJMEApplet($MolString, $StrViewerCodeBase, \%StrViewerParams);
 552     $ValueTag = SetupHTMLTableRowDataValue($Value, $White);
 553   }
 554   else {
 555     $ValueTag = SetupHTMLTableRowDataValue($Value);
 556   }
 557   if ($SettingUpCmpdSummaryPage) {
 558     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 559   }
 560   print $HTMLFileRef $ValueTag;
 561 }
 562 
 563 # Setup Marvin display...
 564 sub SetupMarvinDisplay {
 565   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 566   my($MolString, $AppletBGColor, $Value, $ValueTag, $AppletName);
 567 
 568   $Value = "";
 569   ($MolString) = split "$MolEndTag", $CmpdString;
 570   if (IsNotEmpty($MolString)) {
 571     $AppletBGColor = SetupStructureBGColor($RowNum);
 572     $MolString .= "$MolEndTag";
 573 
 574     $AppletName = "MView" . $CmpdNum;
 575     $StrViewerParams{name} = $AppletName;
 576     if (!$SettingUpCmpdSummaryPage) {
 577       if (!$StrBgColorSpecified) {
 578 	$StrViewerParams{bgcolor} = $AppletBGColor;
 579       }
 580     }
 581     $Value = SetupStrViewerMarvinViewApplet($MolString, $StrViewerCodeBase, \%StrViewerParams);
 582     $ValueTag = SetupHTMLTableRowDataValue($Value);
 583   }
 584   else {
 585     $ValueTag = SetupHTMLTableRowDataValue($Value);
 586   }
 587   if ($SettingUpCmpdSummaryPage) {
 588     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 589   }
 590   print $HTMLFileRef $ValueTag;
 591 }
 592 
 593 # Setup Jmol display...
 594 sub SetupJmolDisplay {
 595   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 596   my($MolString, $AppletBGColor, $Value, $ValueTag, $AppletName);
 597 
 598   $Value = ""; $ValueTag = "";
 599   ($MolString) = split "$MolEndTag", $CmpdString;
 600   if (IsNotEmpty($MolString)) {
 601     $AppletBGColor = SetupStructureBGColor($RowNum);
 602     $MolString .= "$MolEndTag";
 603 
 604     # Make sure MolName line is not empty; otherwise, JMol doesn't display structure...
 605     my(@MolLines) = split "\n", $MolString;
 606     if (IsEmpty($MolLines[0])) {
 607       $MolLines[0] = "Cmpd${CmpdNum}";
 608       $MolString = join "\n", @MolLines;
 609     }
 610 
 611     # Setup the applet...
 612     $AppletName = "Jmol" . $CmpdNum;
 613     $StrViewerParams{name} = $AppletName;
 614     if (!$SettingUpCmpdSummaryPage) {
 615       if (!$StrBgColorSpecified) {
 616 	$StrViewerParams{bgcolor} = $AppletBGColor;
 617       }
 618     }
 619     $Value = SetupStrViewerJmolApplet($MolString, $StrViewerCodeBase, \%StrViewerParams);
 620     $ValueTag = SetupHTMLTableRowDataValue($Value);
 621   }
 622   else {
 623     $ValueTag = SetupHTMLTableRowDataValue($Value);
 624   }
 625   if ($SettingUpCmpdSummaryPage) {
 626     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 627   }
 628   print $HTMLFileRef $ValueTag;
 629 }
 630 
 631 # Setup Chime display...
 632 sub SetupChimeDisplay {
 633   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 634   my($MolString, $BGColor, $Value, $ValueTag, $MolFileRef);
 635 
 636   $Value = "";
 637   ($MolString) = split "$MolEndTag", $CmpdString;
 638   if (IsNotEmpty($MolString)) {
 639     $BGColor = SetupStructureBGColor($RowNum);
 640     $MolString .= "$MolEndTag";
 641     # Write out MOL file...
 642     $MolFileRef = SetupMOLFile($Index, $TableNum, $MolString, $CmpdNum);
 643     # Setup the applet...
 644     if (!$SettingUpCmpdSummaryPage) {
 645       if (!$StrBgColorSpecified) {
 646 	$StrViewerParams{bgcolor} = $BGColor;
 647       }
 648     }
 649     $Value = SetupStrViewerChimePlugIn($MolFileRef, \%StrViewerParams);
 650     $ValueTag = SetupHTMLTableRowDataValue($Value);
 651   }
 652   else {
 653     $ValueTag = SetupHTMLTableRowDataValue($Value);
 654   }
 655   if ($SettingUpCmpdSummaryPage) {
 656     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 657   }
 658   print $HTMLFileRef $ValueTag;
 659 }
 660 
 661 # Setup displays for various viewers available from CambridgeSoft...
 662 sub SetupCambridgeSoftDisplay {
 663   my($ViewerType, $Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 664   my($MolString, $BGColor, $Value, $ValueTag, $MolFileRef, $Name);
 665 
 666   $Value = "";
 667   ($MolString) = split "$MolEndTag", $CmpdString;
 668   if (IsNotEmpty($MolString)) {
 669     $BGColor = SetupStructureBGColor($RowNum);
 670     $MolString .= "$MolEndTag";
 671     # Write out MOL file...
 672     $MolFileRef = SetupMOLFile($Index, $TableNum, $MolString, $CmpdNum);
 673     # Setup the viewer...
 674     $Name = "CS" . $CmpdNum;
 675     if ($ViewerType =~ /^Chem3DActiveX$/) {
 676       # Use white background for Chem3D and cell; otherwise, it doesn't look good:
 677       # cell size is larger than Chem3D window size and different colors don't work
 678       $BGColor = $White;
 679       $StrViewerParams{name} = $Name;
 680       if (!$SettingUpCmpdSummaryPage) {
 681 	if (!$StrBgColorSpecified) {
 682 	  $StrViewerParams{bgcolor} = $BGColor;
 683 	}
 684       }
 685       $Value = SetupStrViewerChem3DActiveX($MolFileRef, \%StrViewerParams);
 686       $ValueTag = SetupHTMLTableRowDataValue($Value, $BGColor);
 687     }
 688     elsif ($ViewerType =~ /^ChemDrawActiveX$/i) {
 689       # BGColor is not supported. So, make it all white...
 690       $BGColor = $White;
 691       $StrViewerParams{name} = $Name;
 692       if (!$SettingUpCmpdSummaryPage) {
 693 	if (!$StrBgColorSpecified) {
 694 	  $StrViewerParams{bgcolor} = $BGColor;
 695 	}
 696       }
 697       $Value = SetupStrViewerChemDrawActiveX($MolFileRef, \%StrViewerParams);
 698       $ValueTag = SetupHTMLTableRowDataValue($Value, $BGColor);
 699     }
 700     elsif ($ViewerType =~ /^ChemDrawPlugIn$/i) {
 701       # BGColor is not supported. So, make it all white...
 702       $BGColor = $White;
 703       if (!$SettingUpCmpdSummaryPage) {
 704 	if (!$StrBgColorSpecified) {
 705 	  $StrViewerParams{bgcolor} = $BGColor;
 706 	}
 707       }
 708       $Value = SetupStrViewerChemDrawPlugIn($MolFileRef, \%StrViewerParams);
 709       $ValueTag = SetupHTMLTableRowDataValue($Value, $BGColor);
 710     }
 711   }
 712   else {
 713     $ValueTag = SetupHTMLTableRowDataValue($Value);
 714   }
 715   if ($SettingUpCmpdSummaryPage) {
 716     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 717   }
 718   print $HTMLFileRef $ValueTag;
 719 }
 720 
 721 # Setup Accelrys Viewer ActiveX display...
 722 sub SetupViewerAccelrysActiveXDisplay {
 723   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 724   my($MolString, $BGColor, $Value, $ValueTag, $Name, $MolFileRef);
 725 
 726   $Value = "";
 727   ($MolString) = split "$MolEndTag", $CmpdString;
 728   if (IsNotEmpty($MolString)) {
 729     $BGColor = SetupStructureBGColor($RowNum);
 730     $MolString .= "$MolEndTag";
 731     # Write out MOL file. Accelrys ActiveX viewer doesn't load mol files with relative path names.
 732     # So, set up a complete path name for now; however, it may lead to issues during web
 733     # deployment.
 734     my($CompletePath) = 1;
 735     $MolFileRef = SetupMOLFile($Index, $TableNum, $MolString, $CmpdNum, $CompletePath);
 736     # Setup the viewer...
 737     $Name = "ViewerActiveX" . $CmpdNum;
 738     if (!$SettingUpCmpdSummaryPage) {
 739       if (!$StrBgColorSpecified) {
 740 	$StrViewerParams{bgcolor} = $BGColor;
 741       }
 742     }
 743     $StrViewerParams{name} = $Name;
 744     $Value = SetupStrViewerAccelrysActiveX($MolFileRef, \%StrViewerParams);
 745     $ValueTag = SetupHTMLTableRowDataValue($Value);
 746   }
 747   else {
 748     $ValueTag = SetupHTMLTableRowDataValue($Value);
 749   }
 750   if ($SettingUpCmpdSummaryPage) {
 751     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
 752   }
 753   print $HTMLFileRef $ValueTag;
 754 }
 755 
 756 
 757 # Setup structure background color...
 758 sub SetupStructureBGColor {
 759   my($RowNum) = @_;
 760   my($BGColor);
 761 
 762   $BGColor = "";
 763   if ($ShadeRowsStatus) {
 764     $BGColor =  ($RowNum % 2) ? $OddRowsShadeColor : $EvenRowsShadeColor;
 765   }
 766   else {
 767     $BGColor = $White;
 768   }
 769   return $BGColor;
 770 }
 771 
 772 # Setup  MDL MOL file...
 773 sub SetupMOLFile {
 774   my($Index, $TableNum, $MolString, $CmpdNum, $CompletePath);
 775   my($SubMolDir, $MolFileName, $MolFile, $MolFileRef);
 776 
 777   $CompletePath = "";
 778   if (@_ == 5) {
 779     ($Index, $TableNum, $MolString, $CmpdNum, $CompletePath) = @_;
 780   }
 781   else {
 782     ($Index, $TableNum, $MolString, $CmpdNum) = @_;
 783   }
 784 
 785   $SubMolDir = $SDFilesSubMolDir[$Index];
 786   $MolFileName = $SDFilesHTMLRoot[$Index] . "Cmpd" . $CmpdNum . ".mol";
 787   $MolFile = $SubMolDir . "\/" . $MolFileName;
 788 
 789   open MOLFILE, ">$MolFile" or die "Error: Can't open $MolFile: $! \n";
 790   print MOLFILE "$MolString\n";
 791   close MOLFILE;
 792 
 793   if ($CompletePath) {
 794     my($CWD, $NewCWD);
 795     $CWD = cwd();
 796     $NewCWD = ConvertCygwinPath($CWD);
 797     $MolFileRef = $NewCWD . "\/" . $SDFilesTopHTMLDir[$Index] .  "\/mol\/$MolFileName" ;
 798   }
 799   else {
 800     $MolFileRef = ($TableNum == 1) ? ".\/mol\/$MolFileName" : "..\/mol\/$MolFileName";
 801   }
 802 
 803   return $MolFileRef;
 804 }
 805 
 806 # Setup a link to structure and other available information...
 807 sub SetupStructureLink {
 808   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
 809   my($CmpdHTMLFileRef, $Value);
 810 
 811   $CmpdHTMLFileRef = SetupCompoundSummaryFileAndLink($Index, $TableNum, $CmpdString, $CmpdNum);
 812 
 813   if ($Options{strlinktype} =~ /^button$/i) {
 814     $Value = SetupHTMLButtonRef("View", $CmpdHTMLFileRef);
 815   }
 816   else {
 817     $Value = SetupHTMLHRef("View", $CmpdHTMLFileRef);
 818   }
 819   print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
 820 }
 821 
 822 # Setup HTML compound summary file and link...
 823 sub SetupCompoundSummaryFileAndLink {
 824   my($Index, $TableNum, $CmpdString, $CmpdNum) = @_;
 825   my($CmpdHTMLFile, $CmpdHTMLFileName, $CmpdHTMLFileRef, $CSSRef, @CmpdLines, $Label, %DataFieldValues, $Value, $Tag);
 826 
 827   # Setup compound file names...
 828   $CmpdHTMLFileName = $SDFilesHTMLRoot[$Index] . "Cmpd" . $CmpdNum . ".html";
 829   $CmpdHTMLFile = $SDFilesSubHTMLDir[$Index] . "\/" . $CmpdHTMLFileName;
 830 
 831   # Setup stylesheet reference....
 832   $CSSRef = "";
 833   if ($Options{stylesheet} =~ /^old$/i) {
 834     $CSSRef = $Options{stylesheetname};
 835   }
 836   else {
 837     $CSSRef = "..\/" . $SDFilesHTMLRoot[$Index] . ".css";
 838   }
 839 
 840   # Write out compound data in a new HTML file. For summary page, usage of even and odd row shade color
 841   # is reversed: it causes structure background to be white by default...
 842   open CMPDHTMLFILE, ">$CmpdHTMLFile" or die "Error: Can't open $CmpdHTMLFile: $! \n";
 843   print CMPDHTMLFILE SetupHTMLPageHeader($StrLinkTitle, $CSSRef, $StrViewerJSFileRef);
 844 
 845   if ($StrViewerJSFileRef) {
 846     print CMPDHTMLFILE SetupStrViewerJSInitCmd($StrViewerType, $StrViewerCodeBase);
 847   }
 848 
 849   if ($StrLinkTitleDisplay) {
 850     print CMPDHTMLFILE SetupHTMLPageTitle($StrLinkTitle, "center");
 851   }
 852   else {
 853     print CMPDHTMLFILE SetupHTMLEmptyLines(1);
 854   }
 855   print CMPDHTMLFILE SetupHTMLAlignmentBegin("center");
 856 
 857   # Setup structure display ...
 858   print CMPDHTMLFILE SetupHTMLTableHeader(0, 5, 2);
 859 
 860   print CMPDHTMLFILE SetupHTMLTableRowHeader("center", "#ffffff", "middle");
 861 
 862   SetupStructureDisplayForCmpdSummaryPage($Index, $CmpdString, $CmpdNum, \*CMPDHTMLFILE);
 863   print CMPDHTMLFILE $RowEndTags;
 864 
 865   if ($Options{strlinkmode} =~ /^plain$/i) {
 866     print CMPDHTMLFILE SetupHTMLTableRowHeader("center", $StrLinkShadeColor);
 867     $Tag = SetupHTMLTableRowDataValue("");
 868     print CMPDHTMLFILE $Tag;
 869     print CMPDHTMLFILE $RowEndTags;
 870   }
 871 
 872   print CMPDHTMLFILE SetupHTMLTableRowHeader("left", "", "middle");
 873   # Start a new table with two columns, one each for data field labels and values, in
 874   # current column...
 875   print CMPDHTMLFILE SetupHTMLTableColumnHeader();
 876   print CMPDHTMLFILE SetupHTMLAlignmentBegin("left");
 877   print CMPDHTMLFILE SetupHTMLTableHeader(0, 5, 2);
 878 
 879   # Setup table for other available data...
 880   my($CmpdRowHeaderTags);
 881   $CmpdRowHeaderTags = SetupHTMLTableRowHeader("left", "", "middle");
 882 
 883   @CmpdLines = split "\n", $CmpdString;
 884   %DataFieldValues = GetCmpdDataHeaderLabelsAndValues(\@CmpdLines);
 885   my($LabelWrapLength, $ValueWrapLength, $LabelColWidth);
 886   $LabelWrapLength = 30; $ValueWrapLength = 60; $LabelColWidth = 40;
 887   for $Label (sort keys %DataFieldValues) {
 888     $Value =  $DataFieldValues{$Label};
 889     $Label .= ":";
 890     if ($Label && (length($Label) > $LabelWrapLength)) {
 891       $Label = WrapText($Label,  $LabelWrapLength, "<br>");
 892     }
 893     print CMPDHTMLFILE $CmpdRowHeaderTags;
 894     if ($Options{strlinkmode} =~ /^plain$/i) {
 895       $Tag = SetupHTMLTableRowDataValue($Label, "", "", 1);
 896     }
 897     else {
 898       $Tag = SetupHTMLTableRowDataValue($Label, $StrLinkShadeColor);
 899     }
 900     $Tag = InsertHTMLTags(