#!/usr/local/bin/perl5 -w
# Copyright InfoMall May 1995
#
# Version 0.71 27 June 1995
# Support for relative path names added
# .71: Incorrect processing of blank lines at end of outline/processed files
#      addressed
# Version 0.72 2 July 1995
# Some support for Powerpoint added
# Version 0.73 15 July 1995 Minor errors in alias corrected
# Version 0.75 3 Sept 1995 More output options -- prettyprint/usedfoilslist
# Version 0.8  5 September 95 Support for Foreign formats in mixed scripts
# Version 0.81 October 13 95 -- Abtracts can be in any place in foilset -- foiln syntax
#                               Multiple Options to let scripts override default master
# Version 0.9  October 27 enhancements to support WebFoil
# Version 0.92 July 96 Netscape 3.0 / PPT Internet Assistant / Audio Support Changes
#
# Program to organize multiple Persuasion(Powerpoint) foilsets under WWW
# Written by Geoffrey Fox March--May 1995
# If it looks like Fortran or C written in PERL, thats what you would expect
# for one's first PERL program.
# Can be freely used copied and distributed but NO guarantees
# 
# Execute as wwwfoil.pl CONTROL SESSION
# CONTROL defines files to be read and written -- these include:
# ORIGINAL is input(outline) file from Persuasion
# PROCOPTIONS defines preferences(options)
# PROCESSED will hold processed Persuasion foils as a stream
# WWWTEMPLATE will define templates for directory of WWW material
# SCRIPT defines for multiple foilsets the selection to be used
# ALIAS lists URL's and their aliases(sort-codes) and default link names
#
# WWWDIR is directory (don't end with slash) where information to be written
#        (wwwdirwritten) or stored (wwwdir)
# WWWSERVER is Web server for each foilset
#
# ABSTEMP is temporary file to hold abstract
# PERSTEMP is temporary file to hold processed foils
#
# SESSION is optional and defines a file with session parameters
#
# %displayparms holds global parameters used in templates
%displayparms =
( "col1",'',"col2",'',"col3",'',"col4",'',"col5",'',
  "size1",24,"size2",14,"size3",12,
  "font1",'',"font2",'',"font3",'',
  "app1",'',"app2",'',"app3",'','scriptaddon','','audioline','',
  "browser",'default');
#
%controlvocab =
( "procoptions",0,"moreprocoptions",0,"original",0,"processed",0,"label",0,"name",0,"load",2,
  "abstract",0,"master",1,"wwwtemplate",0,"wwwserver",0,"wwwdir",0,"makelink",0,"relative",0,
  "script",0,"contd",0,"wwwdirwritten",0,"foreign",0,"comment",1001);
#
%scriptvocab =
( "title",101,"bullet1",102,"bullet2",103,"bullet3",103,"bullet4",104,
  "htmlline",100,"contd",0,"html",25,"endhtml",23,"foils",110);
#
%procoptvocab =
 ( "criticalmissing",0,"somemissing",0,"seealso",0,"nogifversion",0,"noimageversion",0,
 "author",0, "date",0,,"datemod",0,"event",0,"source",0,
 "abstract",0,"addsource",0,"blanks",0,"contd",0,"powerpoint",0,
 "bulletsongif",0,"bestfoilseturl",0,"name",0,"label",0,
 "runningtitle",0,"titleset",0,"signature",0,"html",0,"endhtml",0);
#
%datavocab =
("abstract",22,"author",21,"beginfoil",1,"name",31,"label",32,
 "bullet1",102,"bullet2",103,"bullet3",104,"bullet4",105,
 "contd",0,"date",27,"datemod",28,"endfoil",51,"endhtml",23,
 "event",24,"html",25,"htmlline",2,"criticalmissing",3,"somemissing",4,
 "nogifversion",5,"getgiffrom",7,"runningtitle",100,"seealso",6,"source",26,
 "signature",30,"title",101,"titleset",29,"getimagefrom",7,"noimageversion",5)	;
#
%sessionvocab =
("landscape",1,"portrait",2,"contd",0,"html",0,"endhtml",0);
#
# Open needed temporary files
open(PERSTEMP,"+>perstemp") || die("\nSorry couldnt Create perstemp \n");
open(ABSTEMP,"+>abstemp") || die("\nSorry couldnt Create abstemp \n");
if(-e 'seporggifdir')	{
	symlink 'seporggifdir','seporgimagedir' unless(-e 'seporgimagedir');
}
#
# Set Today
$today= `date`;
$currentdirectory= `pwd`;
chomp($currentdirectory);
$currentdirectory =~ s%^/tmp_mnt%%; # NPAC fix -- Note difficulties with absolute filenames
$userelativefilenames=0;
#
chomp($today);
$today =~ s/\d\d:\d\d:\d\d ... //;	# Today's Date
#
#	Set Session Parameters
$ImageSizeOption =0;
$imagestring_landscape ='';
$imagestring_portrait = '';
#
# Set overall options for output routine foillineout
# $linesize is output size for lines
# $newlinetobr controls treatment of embedded newlines
# $newlinetobr=0 gives newline on output while
# $newlinetobr=1 outputs <br> in lines
# $nonewlines=1 is used in metadata generation to avoid embedded <br> or newlines
# $prettyprint if nonzero specifies special format option (<pre>) for output
$linesize=80;
$newlinetobr=0;
$nonewlines=0;
$prettyprint=0;
$oldprettyprint=0;
#
&readsession($ARGV[1]) if(defined($ARGV[1]));
#
# Set current number of foilsets
$foilset_ct=0;
#
# Set %tagtestvocab, %tagoutvocab
foreach $mem (keys %datavocab) {
	$tagtestvocab{ $datavocab{$mem} } = $mem;
	$tagoutvocab{ $datavocab{$mem} } = "\u${mem}:" ;
}
#
#	Read Control data according to controlvocab
#	The following parameters define what will be in presentation
#
#	$usedfoilset_ct 	Number of Involved foilsets
#	@usedfoilsets		List of involved foil sets
#
#	$totalfoils_ct		Number of involved foils
#	@listoffoilsets		For each foil the foilset it comes from
#				This foilset number is pointer into total 
#				foilset (0..$totalfoilset_ct-1) NOT the 
#				current selection in 
#   				@usedfoilsets(0..$usedfoilset_ct-1)
#	@listoffoils		For each foil the numeric foil number in foilset
#				Note numeric foil numbers START at 1 but indices
#				in @listoffoilsets/foils start at 0
#				abstracts denoted as numeric foil number 0
#
#	$totalscript_ct		Number of involved script lines
#	@typeofscriptline	this is a foil if -1,  additional script line
#				held in $script_list/_html/_type if 1
#	@indexofscriptline	pointer to @listoffoils/foilsets if type -1
#				else pointer to entry in 
#				@script_list/_html/_type
#
# ********************************************************************
#
#	In much data below, there is an HTML option
#	If 0, then input is assumed as ordinary text and special characters
#	are converted to &..; format; if 1 no conversion is done as input
#	is assumed to be HTML already
#
#	$totalfoilset_ct	Number of processed foilsets
#
#	Below each array is labelled by foilset number running from
#				0 ... $totalfoilset_ct-1
#
#	@totalfoilcount		Number of foils in each foilset 
#
#	@abstracttitle		Abstract Title
#	@abstracttitle_html	HTML option for abstract title
#	@keeplinesperabstract	Number of defining lines in abstract
#	@keepabsmissingoption	Missing option for abstract
#	@originalabsrawimage			Location of IMAGE file for abstract
#
#	The following arrays are labelled by both processed foilset
#	number and line number
#	They define data in abstract
#	$keepabslinetype[foilset index][line number]	Type of line as defined
#							in %datavocab
#	$keepabslinehtml[foilset index][line number]	HTML option 
#							for this line
#	$keepabslineitself[foilset index][line number]	Value of abstract 
#							data line itself
#
#	There is also a set of hash arrays labelled by processed foilset
#	number running from 0 .... $totalfoilset_ct
#	$foilsetparms[foilset index]{"name"}	Nickname to be used in
#						 scripts and control
#	$foilsetparms[foilset index]{"usedfoilslist"}	List of foils used
#	$foilsetparms[foilset index]{"wwwserver"} World wide web 
#						  server to be used
#				Only necessary if not same for all sets
#	$foilsetparms[foilset index]{"wwwdir"}	Base directory 
#				(no trailing /) to be used to store foilset 
#				related input and output files on WWW
#	$foilsetparms[foilset index]{"wwwdirwritten"}	Base directory 
#				(no trailing /) to be used to write foilset 
#				related input and output files on UNIX
#	$foilsetparms[foilset index]{"wwwtemplate"}	Input file defining 
#						templates for foilset
#	$foilsetparms[foilset index]{"foreign"}	Define foil type --
#				If non-null, "unusual" non-Persuasion format
#
#	$nametofoilset{"nickname"}	returns foilset index for given nickname
#
#	The following arrays define the individual fils in foilset and 
#	are labelled by foilset index and foilnumber in foilset
#	 (runs from 1 to $totalfoilcount[foilset index])
#
#	@foiltitle		Title of foil
#	@foiltitle_html		HTML option for foil title
#	@keeplinesperfoil	Number of defining lines in foil
#	@keepmissingoption	Missing option for foil
#	@originalfoilrawimage		Location of IMAGE file for foil
#
#	The following arrays are labelled by threee dimensional index
#	[foilset index] [foil number] [line number]
#
#	@keeplinetype	Type of line defining foil(bullet,htmlline etc.)
#			 as defined in %datavocab
#	@keeplinehtml	HTML option for this line
#	@keeplineitself	Value of foil data line itself without key: header
#
#	For each foilset the following hash arrays define overall options
#	There is in each case a companion array with same name but
#	_html appended which contains HTML option
#	$keepoptions[foilset index]{"author"}	Author
#	$keepoptions[foilset index]{"date"}	Date foilset prepared or given
#	$keepoptions[foilset index]{"datemod"}	Date foilset modified
#	$keepoptions[foilset index]{"event"}	Event associated with foilset
#	$keepoptions[foilset index]{"source"}	Source of foilset
#	$keepoptions[foilset index]{"runningtitle"}	Running Title 
#							to be used in Output
#	$keepoptions[foilset index]{"titleset"}		Title of foilSET
#							 (not individual foil)
#	$keepoptions[foilset index]{"signature"}	Text to be used
#						 at end of each HTML foil
#	$keepoptions[foilset index]{"label"}	Label of foilset to be 
#						used in output
#	$keepoptions[foilset index]{"padlabel"}	Right Padded label of foilset to be 
#						used in  fixed format output
#	$keepoptions[foilset index]{"leftpadlabel"}	Left Padded label of foilset to be 
#						used in  fixed format output
#	$keepoptions[foilset index]{"name"}	Nickname of foilset
#	$keepoptions[foilset index]{"bulletsongif"}	if "on" use HTML bullets on IMAGE
#							versions of foils
#	$keepoptions[foilset index]{"bestfoilseturl"}	Best URL for foilset
#
# *******************************************************************
#
&readcontrol($ARGV[0]);
#
# Cleanup at end
close ABSTEMP;
close PERSTEMP;
#
# End Main routine *****************************************************
#
# read session Information from SESSION
sub readsession {
#
	my($sessionfile)=@_;
	my($curkey,$vocabmem,$reading_html,$colon,$possiblekey,$savekey,$entry,$rest,$line);
#
	open(SESSION,$sessionfile) || die("\nSorry couldnt Open Session File ",$sessionfile, "\n");
#
	$reading_html=0;	# Initial HTML option
	undef %sessionvalues;
#
	$curkey='none';
	while( $line=<SESSION> )	{
		chomp($line);
		$colon = index($line,":");
		if ( ($line =~ /^\s/) || $colon < 0 )	{
			die("\nIllegal Continuation Line", $rest,"\n") if $curkey eq 'none';
			$line =~ s/^\s+/ /;
			$sessionvalues{$curkey} = &join($sessionvalues{$curkey},$line);
			next;
		}
		$possiblekey = substr($line ,0, $colon);
		$possiblekey =~ s/\s+//g;
		$savekey=$possiblekey;
		$possiblekey =~ tr/A-Z/a-z/;
		$entry = -1;
		foreach  $vocabmem (keys %sessionvocab) {
			if( $possiblekey eq $vocabmem )	{
				$entry = $sessionvocab{$vocabmem};
				last;
			}
		}
		if( $entry < 0 )	{
			die("\nIllegal key Processing Options ", $possiblekey, "\n");	}	
		if( $possiblekey eq "html" )	{
			$reading_html=1;
			next;
		}
		if( $possiblekey eq "endhtml" )	{
			$reading_html=0;
			next;
		}
		$rest = substr($line, $colon+1);
		if( $possiblekey eq "contd" )	{
			if ($curkey eq 'none')	{
				die("\nIllegal Continuation Line", $rest,"\n");	}
			if( $savekey eq "CONTD" )	{
				$sessionvalues{$curkey} .= "\n" . $rest;
				next;
			}
			$sessionvalues{$curkey} = &join($sessionvalues{$curkey},$rest);
			next;
		}
		$sessionvalues{$possiblekey} = $rest;
		$sessionvalues_html{$possiblekey} = $reading_html;
		$curkey=$possiblekey;
	}	# End loop over input lines
#
#	Process Session Data
	if($sessionvalues{'landscape'})	{
		$imagestring_landscape = $sessionvalues{'landscape'};
		$ImageSizeOption = 1;
	}
	if($sessionvalues{'portrait'})	{
		$imagestring_portrait = $sessionvalues{'portrait'};
		$ImageSizeOption = 1;
	}
	return;
	close(SESSION);
#
} # end readsession
#
#	Read abstract from separate file
sub readabstract	{
	my($inabs)=@_;
#
#
# Overall Initializations
$html=0;	# HTML Conversion Option If 0 convert < > & " if 1 leave input untouched
$foilcount=0;	# Number of foils read
$start=0;	# if zero, no real foil stuff read yet
$pendingreadfoil='';	# Initially nothing has been read in!
$abstract_reading=1;	# We are reading abstract not foils
seek $inabs,0,0;
#
	while( $pendingreadfoil || ($pendingreadfoil=<$inabs>) )	{
		&readfoil($inabs);
	}
}	# End reading abstract from a file
#
# Output Abstract as Coded File
sub outabstract	{
	my($outabs)=@_;
	my($imageset,$ikeep,$i,$entry,$pr);
#
	$currenthtmloption=0;
	seek $outabs,0,0;
	print $outabs "Endhtml:\n" ;
	if( $pr=$foilsource[$foilset_ct] )	{
		$pr= $pr . '/';
	}
	else	{
		if( ($pr=$persoptions{"addsource"}) )	{
			$foilsource[$foilset_ct]=$pr;
			$pr .= '/'
    		}
		else	{
			$pr= ' ';
		}
	}
	print $outabs ("Beginfoil:",$pr,"Abstract\n");
	&printmiss($outabs);
	$imageset=0;
#
	$ikeep=0;
	for($i=0; $i <= $curline ; $i++)	{
		next if( ($entry=$linetype[$i]) ==22 );
		next if( $entry==1 );
		next if( $entry==51 );
		next if ( $entry >=3 && $entry <=6 );
		next if $persoptions{ $tagtestvocab{$entry} };
		outdata( $tagoutvocab{$entry} . $foilline[$i] , $line_html[$i],$outabs);
		$keepabslinetype[$foilset_ct][$ikeep]=$entry;
		$keepabslinehtml[$foilset_ct][$ikeep]=$line_html[$i];
		$keepabslineitself[$foilset_ct][$ikeep]=$foilline[$i];
		$ikeep++;
		if($entry == 7)	{ #	IMAGE position
			$originalabsrawimage[$foilset_ct]=$foilline[$i];
    			$imageset=1;
		}
	}
	if($imageset==0 && $originalabsrawimage[$foilset_ct] )	{
		print $outabs "Getimagefrom:",$originalabsrawimage[$foilset_ct],"\n";
	}
#
	$keeplinesperabstract[$foilset_ct]= $ikeep;
	$keepabsmissingoption[$foilset_ct]= $missingoption;
	print $outabs "Endfoil:\n";
	$abstract_option= 0;
}	# End output of abstract in coded form
#
sub printmiss	{ # Print generalized seealso message
	my($outmiss)=@_;
#
	print $outmiss "Criticalmissing:" if( $missingoption==1 )	;
	print $outmiss "Somemissing:" if( $missingoption==2 )	;
	print $outmiss "Seealso:" if( $missingoption==3 )	;
	print $outmiss "Noimageversion:" if( $missingoption==4 )	;
	print $outmiss "\n";
#
}	# End output of seealso/missing message
#
# read information from CONTROL
sub readcontrol {
#
	my($controlfile)=@_;
	my($foil1,$foilset1,$com,$test,$list,$i,$j,$k,$len,$curkey,$vocabmem,$colon,$possiblekey,$savekey,$entry,$rest,$line,$wwwtemplate,$scriptfile,$new,$old,$foilset,$seporgimagedir,$wwwserver_old,$wwwdirwritten,$newdirectory,$mode,$imagestem);
# $wwwdir is global
#
	open(CONTROL,$controlfile) || die("\nSorry couldnt Open Control file ",$controlfile, "\n");
	$curkey='none';
	undef %controloptions;
	$control_ct=0;
#
	while( $line=<CONTROL> )	{
		chomp($line);
		$colon = index($line,":");
		if ( ($line =~ /^\s/) || $colon < 0 )	{
			die("\nIllegal Continuation Line", $rest,"\n") if $curkey eq 'none';
			$line =~ s/^\s+/ /;
			$controloptions[$control_ct]{$curkey} = &join($controloptions[$control_ct]{$curkey},$line);
			next;
		}
		$possiblekey = substr($line ,0, $colon);
		$possiblekey =~ s/\s+//g;
		$savekey=$possiblekey;
		$possiblekey =~ tr/A-Z/a-z/;
		$entry = -1;
		foreach  $vocabmem (keys %controlvocab) {
			if( $possiblekey eq $vocabmem )	{
				$entry = $controlvocab{$vocabmem};
				last;
			}
		}
		if( $entry < 0 )	{
			die("\nIllegal key Control Options ", $possiblekey, "\n");	}	
		$rest = substr($line, $colon+1);
		if( $possiblekey eq "contd" )	{
			if ($curkey eq 'none')	{
				die("\nIllegal Continuation Line", $rest,"\n");	}
			if( $savekey eq "CONTD" )	{
				$controloptions[$control_ct]{$curkey} .= "\n" . $rest;
				next;
			}
			$controloptions[$control_ct]{$curkey} = &join($controloptions[$control_ct]{$curkey},$rest);
			next;
		}
		if($possiblekey eq 'relative')	{
			$userelativefilenames=1;
			next;
		}
		++$control_ct if defined $controloptions[$control_ct]{$possiblekey};
		$rest =~ s%/$%% if( $possiblekey eq 'wwwdir' || $possiblekey eq 'wwwdirwritten');
		$controloptions[$control_ct]{$possiblekey} = $rest;
		$curkey=$possiblekey;
#
#	Read options and original file if requested
		next unless $entry==2;	# Load command
		$wwwdir=$controloptions[$control_ct]{"wwwdir"};
		$wwwdir= '.' unless defined($wwwdir);
		$controloptions[$control_ct]{"wwwdir"}=$wwwdir;
		$wwwdirwritten=$controloptions[$control_ct]{"wwwdirwritten"};
		$wwwdirwritten=$wwwdir unless defined($wwwdirwritten);
		$controloptions[$control_ct]{"wwwdirwritten"}=$wwwdirwritten;
		$controloptions[$control_ct]{"load"} = $foilset_ct;
		chdir $wwwdirwritten;
		&readopt($controloptions[$control_ct]{"procoptions"},$controloptions[$control_ct]{"moreprocoptions"});
		$controloptions[$control_ct]{"label"}=$persoptions{"label"} if($persoptions{"label"});
		$controloptions[$control_ct]{"name"}=$persoptions{"name"} unless($controloptions[$control_ct]{"name"});
		print "Loading set ",$foilset_ct," ",$controloptions[$control_ct]{"label"}," from ",$wwwdir,"\n";
		if( exists($controloptions[$control_ct]{"foreign"}) )	{
			$controloptions[$control_ct]{"foreign"}='on' unless (defined($controloptions[$control_ct]{"foreign"}))&& ($controloptions[$control_ct]{"foreign"} ne '');
			&control_readforeignfoil($controloptions[$control_ct]{"original"},$controloptions[$control_ct]{"foreign"});
		}
		else	{
			$controloptions[$control_ct]{"foreign"}='';
			&control_readfoil($controloptions[$control_ct]{"original"},$controloptions[$control_ct]{"processed"});
		}
		$control_setpointer[$foilset_ct]=$control_ct;
		chdir $currentdirectory;
		++$foilset_ct;
		++$control_ct;
		}	# End loop over input lines
#
	$totalfoilset_ct=$foilset_ct;
	$totalcontrol_ct=$control_ct+1;
	die("No foilsets defined")	unless $totalfoilset_ct;
	close(CONTROL);
#
#	Set up foilset to label maps
	$labellength=0;
	for($i=0;$i<$totalfoilset_ct;$i++)	{
		$j=$control_setpointer[$i];
#
		$test=$controloptions[$j]{"label"};
		$test= "Foilset" . ($i+1)	unless ($test || ( $totalfoilset_ct == 1 ));
		$keepoptions[$i]{"label"}=$test;
		$len=length($test);
		$labellength=$len unless $labellength >= $len;
		$keepoptions_html[$i]{"label"}=0;
#
		$test=$controloptions[$j]{"name"};
		unless($test)	{
			$test='Foilset'.($i+1) unless ($test=$controloptions[$j]{"label"});
		}
		$foilsetparms[$i]{"name"}=$test;
		$test =~ tr/A-Z/a-z/;
		$nametofoilset{$test}=$i;
#
		$foilsetparms[$i]{"wwwserver"}=$controloptions[$j]{"wwwserver"};
		$foilsetparms[$i]{"wwwdir"}=$controloptions[$j]{"wwwdir"};
		$foilsetparms[$i]{"wwwdirwritten"}=$controloptions[$j]{"wwwdirwritten"};
		$foilsetparms[$i]{"wwwtemplate"}=$controloptions[$j]{"wwwtemplate"};
		$foilsetparms[$i]{"foreign"}=$controloptions[$j]{"foreign"};
		&setupfoilsetaudio($i);
	}
#
#	Process Scripts and then templates
	for($i=0;$i<$totalcontrol_ct;$i++)	{
		next unless ($scriptfile=$controloptions[$i]{"script"});
		$scriptfile =~ s/\s*//;
		$scriptabstract=$controloptions[$i]{"abstract"};
		$scriptabstract='masterabstract' unless defined($scriptabstract);
		if( $scriptfile eq 'single' || $scriptfile eq 'simple' )	{ # Single Simple style File
#
#	Fake a simple script invoking all foils of current foilset
			next unless ( (defined($j=$controloptions[$i]{"load"})) || (($i>0)&&defined($j=$controloptions[$i-1]{"load"})) );
			$multi=0;
			$usedfoilset_ct=1;
			$usedfoilsets[0]=$j;
			$masterfoilset=$j;
			$wwwdir=$foilsetparms[$j]{"wwwdir"};
			$wwwdirwritten=$foilsetparms[$j]{"wwwdirwritten"};
			$wwwserver=$foilsetparms[$j]{"wwwserver"};
			$wwwtemplate=$foilsetparms[$j]{"wwwtemplate"};
			$totalfoils_ct=$totalfoilcount[$j];
			$totalscript_ct=$totalfoilcount[$j];
			$foilsetparms[$j]{"usedfoilslist"}='';
			$scriptabsrawimage=$absrawimage[$j];
#
#	Set foils to be used
			for($k=0;$k<$totalfoils_ct;$k++)	{
				$listoffoilsets[$k]=$j;	# All foils from same set
				$listoffoils[$k]=$k+1;	# Foil numbering starts  at 1 not 0 !
				$typeofscriptline[$k]= -1;	# Script only has foils in it
				$indexofscriptline[$k]=$k;	# script index to $listoffoilsets/foils
				$foilsetparms[$j]{"usedfoilslist"} .= ($k+1) . ' ';
			}
			&readwwwtemplate($wwwtemplate,$wwwdir,$wwwdirwritten);
		}	# End case of simple script
#
#		Case of complex script read from a file
		else	{	# $scriptfile not simple
			die("Cannot load and define complex script simultaneously\n")	if(defined($controloptions[$i]{"load"}));
			$multi=1;
			$test=$controloptions[$i]{"master"};
			if( defined($test))	{
				$test =~ tr/A-Z/a-z/;
				die("Illegal Master Foilset name ",$test,"\n") unless defined($masterfoilset=$nametofoilset{$test});
			}
			else	{
				die("Master foil set undefined\n")	unless defined($masterfoilset=$controloptions[$i-1]{"load"});
			}
#
#	Define foils in foilset with script
			&readscript($scriptfile,$masterfoilset);
#
#	Set up directories
			$wwwdir=$controloptions[$i]{"wwwdir"};
			$wwwdir= '.' unless defined($wwwdir);
			$controloptions[$i]{"wwwdir"}=$wwwdir;
			$wwwdirwritten=$controloptions[$i]{"wwwdirwritten"};
			$wwwdirwritten=$wwwdir unless defined($wwwdirwritten);
			$controloptions[$i]{"wwwdirwritten"}=$wwwdirwritten;
			$wwwserver=$controloptions[$i]{"wwwserver"};
#
#	Check if legal directory
			for($k=0;$k<$usedfoilset_ct;$k++)	{
				$foilset=$usedfoilsets[$k];
				next if($wwwdirwritten ne $foilsetparms[$foilset]{"wwwdirwritten"});
				$wwwserver_old=$foilsetparms[$foilset]{"wwwserver"};
				next if( defined($wwwserver) && defined($wwwserver_old) && ($wwwserver ne $wwwserver_old));
				die "Duplicate wwwdirwritten directories for script and foilset ",$foilset, "\n";
			}
#
#	Set up Audio for a Script
			&setupscriptaudio($scriptabstract,$masterfoilset);
#
#	This does not work if different servers for foilsets
#	Use local/seporgimagedir in this case to grab off original source
			if($seporgimagedir=$controloptions[$i]{"makelink"})	{	# Create links for foils
				$seporgimagedir = 'seporgimagedir' if($seporgimagedir eq 'seporggifdir');
				$seporgimagedir =~ s%/$%% ;
				$newdirectory = $seporgimagedir;
				$newdirectory = $wwwdirwritten . '/' . $newdirectory unless($wwwdirwritten eq '.');
				unless(defined(-e $newdirectory))	{
					$mode=0755;
					mkdir $newdirectory,$mode;
				}
				else	{ # Delete old files if clearly safe
					$com='rm '.$newdirectory.'/*';
					system($com)	if $seporgimagedir eq 'seporgimagedir';
				}
				$basedirectory = $currentdirectory . '/';
				$basedirectory = '' if($userelativefilenames == 1);
				for($j=0;$j<$totalfoils_ct;$j++)	{
					$foilset=$listoffoilsets[$j];
					$k=$listoffoils[$j];
					$scriptrawimage[$j+1] = '';
					next if($keepmissingoption[$foilset][$k]==4);
					$wwwserver_old=$foilsetparms[$foilset]{"wwwserver"};
					if(defined($wwwserver_old))	{
						if( $wwwserver ne $wwwserver_old )	{
							print "Cannot create links between different servers for foil ",$j," between servers ",$wwwserver,' * ',$wwwserver_old,"\n" ;
							next;
						}
					}
					$old=$foilsetparms[$foilset]{"wwwdirwritten"}.'/'.$seporgimagedir . '/' .(&externalnumericlabel($k));
					$imagestem = &getimagetype($old);
					$old .= $imagestem;
					$new= $seporgimagedir . '/' . (&externalnumericlabel($j+1));
					$new = $wwwdirwritten . '/' . $new unless($wwwdirwritten eq '.');
					$new .= $imagestem;
					$scriptrawimage[$j+1] = $new; # Set to $old for relative address
					$old= &absolutefile($old);
					$new= &absolutefile($new);
					if(defined(-e $new) || (-l $new) )	{
						print "Didnot create ",$new," as already exists\n";
						next;
					}
					unless(defined(-e $old) || (-l $old) )	{
						print "Warning that file ",$old," does not exist\n";
					}
					$old =  &jumpfoil($new,$old) if($userelativefilenames);
					die "Cannot create Symbolic link from ",$old," to ",$new,"\n"	unless symlink $old,$new;
				}	# End symbolic links for foils
			}       # End creating links for foils
			else	{	# Set scriptrawimage anyway
				die("Currently must specify makelink\n");
			}
#
#	Set up Abstract of script -- $scriptabstract if set explicitly, holds foil number
#	(numbering starting at 1!) in mixed list
#	If not set we default to abstract of master foilset
			if( $scriptabstract eq 'masterabstract' )	{ # Set script abstract
				$scriptabsrawimage= 'seporgimagedir/abstract';
				$scriptabsrawimage .= &getimagetype($foilsetparms[$masterfoilset]{"wwwdirwritten"} .'/'. $scriptabsrawimage);
			}
			else	{
				$scriptabstract =~ s%^[F|f]oil%%;
				die('Error in Script abstract ',$scriptabstract,"\n") if( $scriptabstract < 1 || $scriptabstract > $totalfoils_ct );
				$scriptabsrawimage='seporgimagedir/'. &externalnumericlabel($scriptabstract);
				$scriptabsrawimage .= &getimagetype($wwwdirwritten. '/'. $scriptabsrawimage);
				$foilset1=$listoffoilsets[$scriptabstract-1];
				$foil1=$listoffoils[$scriptabstract-1];
				$abstracttitle[$masterfoilset]=$foiltitle[$foilset1][$foil1];
				$abstracttitle_html[$masterfoilset]=$foiltitle_html[$foilset1][$foil1];
			}
#
#	This does not work if different servers for foilsets
#	Use local/seporgimagedir in this case to grab off original source
			if($seporgimagedir=$controloptions[$i]{"makelink"})	{	# Create links for abstract
				$seporgimagedir = 'seporgimagedir' if($seporgimagedir eq 'seporggifdir');
				$seporgimagedir =~ s%/$%% ;
#
#	Symbolic Links for abstract
				if( $scriptabstract eq 'masterabstract' )       {
					$wwwserver_old=$foilsetparms[$masterfoilset]{"wwwserver"};
					if(defined($wwwserver_old) && ( $wwwserver ne $wwwserver_old ))	{
							print "Cannot create links between different servers for abstract between servers ",$wwwserver,' * ',$wwwserver_old,"\n" ;
					}
					$old=$foilsetparms[$masterfoilset]{"wwwdirwritten"}.'/'.$seporgimagedir . '/abstract';
				}
				else	{ # Abstract not from master
					$old= $wwwdirwritten . '/' . $scriptabsrawimage;
				}
				$old =~ s%\.([^/\.]*)$%%;
				$imagestem = &getimagetype($old);
				$old .= $imagestem;
				$new= $seporgimagedir. '/abstract' . $imagestem;
				$new = $wwwdirwritten . '/' . $new unless($wwwdirwritten eq '.');
				$scriptabsrawimage = $new; # remove (leaving as $old) for relative addressing!
				$old= &absolutefile($old);
				$new= &absolutefile($new);
				if(defined(-e $new) || (-l $new) )	{
					print "Didnot create ",$new," as already exists\n";
				}
				else	{
					unless(defined(-e $old) || (-l $old) )	{
						print "Warning that file ",$old," does not exist\n";
					}
					$old =  &jumpfoil($new,$old) if($userelativefilenames);
					die "Cannot create Symbolic link from ",$old," to ",$new,"\n"	unless symlink $old,$new;
				}
			}	# End creating link for abstract
			$scriptrawimage[0] = $scriptabsrawimage;
#
#	Set Used Foils List
			for($j=0;$j<$totalfoilset_ct;$j++)	{
				$list= '';
				for($k=0;$k <$totalfoils_ct;$k++)	{
					next unless $listoffoilsets[$k] == $j;
					$list .= $listoffoils[$k]. ' ';
				}
				$foilsetparms[$j]{"usedfoilslist"}=$list;
			}
#
			$wwwtemplate=$controloptions[$i]{"wwwtemplate"};
			&readwwwtemplate($wwwtemplate,$wwwdir,$wwwdirwritten);
		}	# End case of complex script
	}	# End loop over control sections $i
	return;
#
} # end readcontrol
#
# read information from SCRIPT to join foils together
sub readscript {
#
	my($scriptfile,$defaultfoilsetnumber)=@_;
	my($curkey,$vocabmem,$reading_html,$colon,$possiblekey,$savekey,$entry,$rest,$line,$lasttype,$i,$j,$k,$apt,$bpt,$len);
#
	open(SCRIPT,$scriptfile) || die("\nSorry couldnt Open Script file ",$scriptfile, "\n");
	$reading_html=0;	# Initial HTML option
	$curkey='none';
	$lasttype=0;
	$script_ct=0;
	undef @script_list;
	undef @script_html;
	undef @script_type;
#
	while( $line=<SCRIPT> )	{
		chomp($line);
		$colon = index($line,":");
		if ( ($line =~ /^\s/) || $colon < 0 )	{
			$line =~ s/^\s+/ /;
			if( $lasttype < 100 )	{
				$lasttype=100;
				$script_list[$script_ct]=$line;
				$script_html[$script_ct]=$reading_html;
				$script_type[$script_ct]=$lasttype;
				++$script_ct;
			}
			else	{
				$script_list[$script_ct] = &join($script_list[$script_ct],$line);
			}
			next;
		}
		$possiblekey = substr($line ,0, $colon);
		$possiblekey =~ s/\s+//g;
		$savekey=$possiblekey;
		$possiblekey =~ tr/A-Z/a-z/;
		$entry = -1;
		foreach  $vocabmem (keys %scriptvocab) {
			if( $possiblekey eq $vocabmem )	{
				$entry = $scriptvocab{$vocabmem};
				last;
			}
		}
		if( $entry < 0 )	{
			die("\nIllegal key Script ", $possiblekey, "\n");	}	
		if( $possiblekey eq "html" )	{
			$reading_html=1;
			next;
		}
		if( $possiblekey eq "endhtml" )	{
			$reading_html=0;
			next;
		}
		$rest = substr($line, $colon+1);
		if( $possiblekey eq "contd" )	{
			if ($curkey eq 'none')	{
				die("\nIllegal Continuation Line", $rest,"\n");	}
			if( $savekey eq "CONTD" )	{
				$script_list[$script_ct] .= "\n" . $rest;
				next;
			}
			$script_list[$script_ct-1] = &join($script_list[$script_ct-1],$rest);
			next;
		}
		$script_list[$script_ct] = $rest;
		$script_html[$script_ct] = $reading_html;
		$script_type[$script_ct] = $entry;
		++$script_ct;
		$lasttype=$entry;
		$curkey=$possiblekey;
		}	# End loop over input lines
#
	close(SCRIPT);
	$totalrawscript_ct=$script_ct;
#
#	Process raw script data
	$usedfoilset_ct=0;
	$totalfoils_ct=0;
	$totalscript_ct=0;
	for($i=0;$i<$totalrawscript_ct;$i++)	{
		if($entry=$script_type[$i] != 110 )	{
			$typeofscriptline[$totalscript_ct]=1;
			$indexofscriptline[$totalscript_ct]=$i;
			++$totalscript_ct;
			next;
		}
		($apt,$bpt)= &interp_script($script_list[$i],$defaultfoilsetnumber);
		$len=@{$apt};
		next unless $len;
#
#	Store foils/foilsets specified in current script line
		for($j=0;$j<$len;$j++)	{
			my($flag);
			$flag=1;
			$typeofscriptline[$totalscript_ct]= -1;
			$indexofscriptline[$totalscript_ct]= $totalfoils_ct;
			$totalscript_ct++;
			$listoffoils[$totalfoils_ct]=$$apt[$j];
			$listoffoilsets[$totalfoils_ct]=$$bpt[$j];
			$totalfoils_ct++;
			for($k=0;$k<$usedfoilset_ct;$k++)	{
				next if($usedfoilsets[$k] != $$bpt[$j]);
				$flag=0;
				last;
			}
			if($flag)	{
				$usedfoilsets[$usedfoilset_ct]=$$bpt[$j];
				$usedfoilset_ct++;
			}
		}
	}
	return;
#
} # end readscript
#
#	Interpret Foil numbers specified in script
sub interp_script	{
#
	my($line,$currentfoilset)=@_;
	my(@a,@b,@fields,$num,$default,$i,$j,$one,$two,$foilsetnum,$begin,$end);
#
	@fields=split(/\s*[,\s]\s*/,$line);
	$num=0;
	$default='';
	for($i=0;$i< @fields;$i++)	{
		next unless $fields[$i];
		($name,$digits)=split(/\//,$fields[$i]);
		unless($digits)	{
			$digits=$name;
			$name='';
		}
		$default=$name	if $name;
		$name=$default	unless $name;
		if( $name )	{
			$name =~ tr/A-Z/a-z/;
			die "Illegal Foilset Name",$name,"\n"	unless defined($foilsetnum=$nametofoilset{$name});
		}
		else	{
			die "No default\n"	unless $currentfoilset >= 0;
			$foilsetnum=$currentfoilset;
		}
		($begin,$end)=split(/\s*-\s*/,$digits);
		unless( $end )	{
			$one= &convertandcheck($begin,$foilsetnum);
			$a[$num]=$one;
			$b[$num]=$foilsetnum;
			$num++;
		}
		else	{
			$one= &convertandcheck($begin,$foilsetnum);
			$two= &convertandcheck($end,$foilsetnum);
			for($j=$one;$j<=$two;$j++)	{
				$a[$num]=$j;
				$b[$num]=$foilsetnum;
				$num++;
			}
		}
	}
	return (\@a,\@b);
#
}	# End Interp_script
#
#	Help interp_script with getting foil number from number or text
sub convertandcheck	{
#
	my($numval,$foilsetnum)=@_;
	my($max);
#
	$max=$totalfoilcount[$foilsetnum];
	$numval =~ s/\s*//g;
	$numval =~ tr/A-Z/a-z/;
	$numval=$max if( $numval eq 'end' );
	$numval=1	if( $numval eq 'begin' );
	$numval=0	if( $numval eq 'abstract' );
	return $numval;
}	# End convertandcheck
#
#
# read dictionary from PROCOPTIONS
sub readopt {
#
	my($procfile,$nextprocfile)=@_;
	my($restart,@ppfields,$curkey,$vocabmem,$reading_html,$colon,$possiblekey,$savekey,$entry,$rest,$line);
#
	open(PROCOPTIONS,$procfile) || die("\nSorry couldnt Open Procoptions ",$procfile, "\n");
#
	$reading_html=0;	# Initial HTML option
	$blank=8;	# Default blanks in a tab
	$powerpoint=0;	# Persuasion =0 Powerpoint=1
	undef %persoptions;
	$restart=2;
#
# set option controlling placement of bullet lines on "IMAGE" pages
# change with bulletsongif: command in options file
	$bulletsongif=0;
#
	while ($restart )	{
		$curkey='none';
		while( $line=<PROCOPTIONS> )	{
			chomp($line);
			$colon = index($line,":");
			if ( ($line =~ /^\s/) || $colon < 0 )	{
				die("\nIllegal Continuation Line", $rest,"\n") if $curkey eq 'none';
				$line =~ s/^\s+/ /;
				$persoptions{$curkey} = &join($persoptions{$curkey},$line);
				next;
			}
			$possiblekey = substr($line ,0, $colon);
			$possiblekey =~ s/\s+//g;
			$savekey=$possiblekey;
			$possiblekey =~ tr/A-Z/a-z/;
			$entry = -1;
			foreach  $vocabmem (keys %procoptvocab) {
				if( $possiblekey eq $vocabmem )	{
					$entry = $procoptvocab{$vocabmem};
					last;
				}
			}
			if( $entry < 0 )	{
				die("\nIllegal key Processing Options ", $possiblekey, "\n");	}	
			if( $possiblekey eq "html" )	{
				$reading_html=1;
				next;
			}
			if( $possiblekey eq "endhtml" )	{
				$reading_html=0;
				next;
			}
			$rest = substr($line, $colon+1);
			if( $possiblekey eq "contd" )	{
				if ($curkey eq 'none')	{
					die("\nIllegal Continuation Line", $rest,"\n");	}
				if( $savekey eq "CONTD" )	{
					$persoptions{$curkey} .= "\n" . $rest;
					next;
				}
				$persoptions{$curkey} = &join($persoptions{$curkey},$rest);
				next;
			}
			$persoptions{$possiblekey} = $rest;
			$options_html{$possiblekey} = $reading_html;
			$curkey=$possiblekey;
			$blank=$rest if $possiblekey eq "blanks";
			$bulletsongif = 1-$bulletsongif if $possiblekey eq "bulletsongif";
		}	# End loop over input lines
	#
		close(PROCOPTIONS);
		last if $restart==1;
		$restart=1;
		last unless $nextprocfile;
		$nextprocfile= $currentdirectory. '/' . $nextprocfile;
		open(PROCOPTIONS,$nextprocfile) || die("\nSorry couldnt Open Procoptions ",$nextprocfile, "\n");
	}	# Loop over $restart
#
	if($bulletsongif)	{
		$persoptions{"bulletsongif"}="on";
		}
	else	{
		$persoptions{"bulletsongif"}="off";
	}
#
#	Process Powerpoint Options
	return unless exists($persoptions{"powerpoint"});
	$powerpoint=1;
	$rest=$persoptions{"powerpoint"};
	$rest =~ s/^\s*//;
	@ppfields=split(/[\s,]+/,$rest);
	$ppcontdlimit=$ppfields[0];
	for($i=0;$i<5;$i++)	{
		$ppbullets[$i]=$ppfields[$i+1];
		die "You must define bullets in powerpoint ",$i," \n"	unless(defined($ppbullets[$i]));
	}
	return;
#
} # end readopt
#
# Read foreign (non persuasion/powerpoint) foils
sub control_readforeignfoil	{
#
	my($original,$foreigntype)=@_;
	my($i,$j,$pointer,$localtitle,$localurl,$localimage,$trailer);
	my($copy,$titlesetforeign,$abstractforeign,$urlforeign,$foilctforeign,@foilsforeign,$line,$lone);
#
	open(ORIGINAL,'<'.$original) || die("\nSorry couldnt Open Original ",$original, "\n");
#
# read raw foreign information -- rest held in conventional options file
	$copy=0;
	$titlesetforeign='';
	$abstractforeign='';
	$urlforeign='';
	$foilctforeign=0;
	while($line=<ORIGINAL>)     {
	        chomp $line;
		$lone=$line; $lone =~ tr/A-Z/a-z/;
		$copy=0 if $lone =~ m%<!--end%;
		$copy=1 if $lone =~ m%<!--title%;
		$copy=2 if $lone =~ m%<!--abstract%;
		$copy=3 if $lone =~ m%<!--url%;
		$copy=4 if $lone =~ m%<!--foilsnumurl%;
		$copy=5 if $lone =~ m%<!--foilsnonumurl%;
		next if $copy ==0;
		$line =~ s%<!--[^-]*-->%%g;
		$line =~ s/[\s]*$//;
		$line =~ s/^[\s]*//;
		next unless $line;
		if($copy==1)	{
			$line =~ s%<[^>]*>%%g;
			next unless $line;
			if($titlesetforeign)	{
				$titlesetforeign .= "\n".$line;
			}
			else	{
				$titlesetforeign=$line;
			}
		}
		if($copy==2)	{
	                $line =~ s%<[^>]*>%%g;
	                next unless $line;
			if($abstractforeign)	{
				$abstractforeign .= "\n".$line;
			}
			else	{
				$abstractforeign=$line;
			}
		}
		if($copy==3)	{
			$line =~ s%<[^>]*>%%g;
	           	next unless $line;
			if($urlforeign)	{
				$urlforeign .= "\n".$line;
			}
			else	{
				$urlforeign=$line;
			}
		}
		if($copy==4)	{
			$line =~ s%<[\s]*[Ll][Ii][\s]*>%%g;
			$line =~ s%<[\s]*[Bb][Rr][\s]*>%%g;
			$line =~ s%(N|n)(A|a)(M|m)(E|e)=[^\s]*%%g;
			unless( $line =~ m%[Hh][Rr][Ee][Ff]% ) {
				$foilsforeign[$foilctforeign] .= "\n".$line if $foilctforeign;
				next;
			}
			++$foilctforeign;
			$foilsforeign[$foilctforeign]=$line;
		}
		if($copy==5)	{
			$line =~ s%<[\s]*[Ll][Ii][\s]*>%%g;
			$line =~ s%<[\s]*[Bb][Rr][\s]*>%%g;
			$line =~ s%(N|n)(A|a)(M|m)(E|e)=[^\s]*%%g;
	     		unless( $line =~ m%[Hh][Rr][Ee][Ff]% ) {
	                        $foilsforeign[$foilctforeign] .= "\n".$line if $foilctforeign;
	                        next;   
	                }
			++$foilctforeign;
			$line =~ s%([Hh][Rr][Ee][Ff][^>]*>\s*)%$1${foilctforeign}:%;
			$foilsforeign[$foilctforeign]=$line;
		}
	}	# End loop over foils of this set on ORIGINAL
#
	close(ORIGINAL);
#
	$totalfoilcount[$foilset_ct]=$foilctforeign;	# Total number of foils
#
	$foreigntype =~ tr/A-Z/a-z/;
	$foreigntype = 'webtools' if $foreigntype =~ m%^webt%;
#
#	Process individual foils
	for($i=1;$i<=$foilctforeign;$i++)	{
		for($j=0;$j<5;$j++)	{
			$keeplinehtml[$foilset_ct][$i][$j]=0;
		}
		$keeplinehtml[$foilset_ct][$i][3]=1;
		$line=$foilsforeign[$i];
		$line =~ m%[^>]*>([^<]*)<.*%;
		$localtitle=$1;
		$localtitle =~ s/^\s*//;
		$foiltitle[$foilset_ct][$i]=$localtitle;
		$foiltitle_html[$foilset_ct][$i]=0;
		$line =~ m%.*[h|H][R|r][E|e][F|f]="([^"]*)".*%;
		$localurl=$1;
		$pointer='See <a href="'.$localurl.'"> Original Foil </a>';
		$originalfoilrawimage[$foilset_ct][$i]='';
		$bestfoilurl[$foilset_ct][$i]=$localurl;
		$keeplineitself[$foilset_ct][$i][0]='Foil:'.$i;
		$keeplineitself[$foilset_ct][$i][1]=$localtitle;
		$keeplineitself[$foilset_ct][$i][2]='';
		$keeplineitself[$foilset_ct][$i][3]=$pointer.'<br>';
		$keeplineitself[$foilset_ct][$i][4]='';
		$keeplinetype[$foilset_ct][$i][0]=1;
		$keeplinetype[$foilset_ct][$i][1]=101;
		$keeplinetype[$foilset_ct][$i][2]=5;
		$keeplinetype[$foilset_ct][$i][3]=2;
		$keeplinetype[$foilset_ct][$i][4]=51;
		$keeplinesperfoil[$foilset_ct][$i]=5;
		$keepmissingoption[$foilset_ct][$i]=4;
#		if( $foreigntype eq 'webtools' )	{ # FURMANSKI IMAGE CONVENTION
#			$localimage = $localurl;
#			$localimage =~ s%html%gif%;
#			$keeplineitself[$foilset_ct][$i][2] = $localimage;
#			$keeplinetype[$foilset_ct][$i][2]=7;
#			$originalfoilrawimage[$foilset_ct][$i]=$localimage;
#			$keepmissingoption[$foilset_ct][$i]=1;
#		}
	}
#
#
#	Save overall options
	$persoptions{"author"}="Geoffrey C. Fox" unless($persoptions{"author"});
	unless($persoptions{"titleset"})	{
		$persoptions{"titleset"}=$titlesetforeign if $titlesetforeign;
	}
	unless($persoptions{"runningtitle"})	{
		$persoptions{"runningtitle"}=$persoptions{"titleset"} if $persoptions{"titleset"}
	}
	unless($persoptions{"bestfoilseturl"})	{
		$persoptions{"bestfoilseturl"}=$urlforeign if $urlforeign;
	}
	$bestfoilseturl[$foilset_ct]=$persoptions{"bestfoilseturl"};
#
	foreach $mem ("author","date","datemod","event","name","label","source","runningtitle","titleset","signature","bulletsongif","bestfoilseturl")	{
		next unless($persoptions{$mem});
		$keepoptions[$foilset_ct]{$mem}=$persoptions{$mem};
		$keepoptions_html[$foilset_ct]{$mem}=$options_html{$mem};
	}
	$keepoptions[$foilset_ct]{"titlesetsize"}= &setcharactersize($keepoptions[$foilset_ct]{"titleset"},$keepoptions_html[$foilset_ct]{"titleset"},'');
	$keepoptions_html[$foilset_ct]{"titlesetsize"}=0;
#
#	Set abstract title
	if($persoptions{"runningtitle"})	{
		$trailer=$persoptions{"runningtitle"};
		$abstracttitle_html[$foilset_ct]=$options_html{"runningtitle"};
	}
	else	{
		$trailer="Presentation";
		$abstracttitle_html[$foilset_ct]=0;
	}
	$abstracttitle[$foilset_ct]="Abstract of " . $trailer;
#
#	Set abstract
	$originalabsrawimage[$foilset_ct]='';
	$keepabsmissingoption[$foilset_ct]=4;
	$keeplinesperabstract[$foilset_ct]=6;
	$keepabslinetype[$foilset_ct][0]=1;
	$keepabslinetype[$foilset_ct][1]=101;
	$keepabslinetype[$foilset_ct][2]=5;
	$keepabslinetype[$foilset_ct][3]=2;
	$keepabslinetype[$foilset_ct][4]=102;
	$keepabslinetype[$foilset_ct][5]=51;
	$keepabslineitself[$foilset_ct][0]='Abstract Foil:';
	$keepabslineitself[$foilset_ct][1]=$abstracttitle[$foilset_ct];
	$keepabslineitself[$foilset_ct][2]='';
	$keepabslineitself[$foilset_ct][3]='See <a href="'.$urlforeign.'> Base Page</a> for more Information<br>';
	$keepabslineitself[$foilset_ct][4]=$abstractforeign;
	$keepabslineitself[$foilset_ct][5]='';
	for($j=0;$j<6;$j++)	{
		$keepabslinehtml[$foilset_ct][$j]=0;
	}
	$keepabslinehtml[$foilset_ct][3]=1;
	$keepabslinehtml[$foilset_ct][1]=$options_html{"runningtitle"};
	$bestabsurl[$foilset_ct]=$urlforeign;
	$bestfoilurl[$foilset_ct][0]=$urlforeign;
#
	return;
#
}	# End Control_readforeignfoil
#
#	Control reading of Single Foil set
#	Parameters are input(ORIGINAL must be there) and if desired
#			output(PROCESSED -- can be null)
sub control_readfoil	{
#
	my($original,$processed)=@_;
	my($test,$teststart,$inabs,$i,$ikeep,$savehtmloption,$abstract_foil);
	my($abstract_test,$entry,$trailer,$imagestem);
#
	open(ORIGINAL,$original) || die("\nSorry couldnt Open Original ",$original, "\n");
#
#	Set up Abstract Option
	$originalabsrawimage[$foilset_ct]='';	# Location of possible IMAGE for abstract
	if( ($teststart=$persoptions{"abstract"}) )	{
		$teststart =~ tr/A-Z/a-z/;
		$teststart =~ s/(\s)*//g;
		$teststart =~ s/(\d*)$//;
		if($1)	{
			$test= $1;
		}
		else	{
			$test=2;
		}
		if ( $teststart eq 'none' ) { 
		$abstract_option = -1; 
		}
		elsif ( $teststart eq 'foil' )	{ 
			$abstract_option=$test; 
		}
		else	{
			$inabs=$persoptions{"abstract"};
			$inabs =~ s/(\s)*//g;
			open(ABSIN,$inabs) || die("\nSorry couldn't open abstract file ",$inabs,"\n");
			&readabstract( ABSIN );
			close(ABSIN);
			&outabstract(ABSTEMP);
		}
	}
	else	{	$abstract_option =2;	}
#
# Overall Initializations for readfoil
	$html=0;	# HTML Conversion Option If 0 convert < > & " if 1 leave input untouched
	$foilcount=0;	# Number of foils read
	$start=0;	# if zero, no real foil stuff read yet
	$pendingreadfoil='';	# Initially nothing has been read in!
	$abstract_reading=0;	# We are reading foils not abstract
#
# Initialize Temporary Foil File
	seek PERSTEMP,0,0;
	print PERSTEMP "Endhtml:\n";
	$currenthtmloption=0;
#
#
#  Read in foils
	while( $pendingreadfoil || ($pendingreadfoil=<ORIGINAL>) )	{
#
		&readfoil(ORIGINAL);
		next if($curline == -1);
#
#	Output main stream of foils
		$abstract_test=$foilno;
		$abstract_test =~ tr/A-Z/a-z/;
		if( $abstract_test eq 'abstract' )	{
			$abstract_foil=1;
			--$foilcount;
		}
		else	{
			$abstract_foil=0;
			print PERSTEMP ("Beginfoil: ",$foilsource[$foilset_ct],'/',$foilno,"\n");
			&printmiss(PERSTEMP);
		#
			$originalfoilrawimage[$foilset_ct][$foilno]='';
			$ikeep=0;
			for( $i=0; $i <= $curline ; $i++ )	{
				next if ( ($entry=$linetype[$i]) ==1 );
				next if ( $entry ==51 );
				next if ( $entry >=3 && $entry <=6 );
		#
		# Don't output option contained in summary information
				next if $persoptions{ $tagtestvocab{$entry} };
				&outdata($tagoutvocab{$entry}.$foilline[$i],$line_html[$i],PERSTEMP);
				$keeplinetype[$foilset_ct][$foilno][$ikeep]=$entry;
				$keeplinehtml[$foilset_ct][$foilno][$ikeep]=$line_html[$i];
				$keeplineitself[$foilset_ct][$foilno][$ikeep]=$foilline[$i];
				$ikeep++;
				$originalfoilrawimage[$foilset_ct][$foilno]=$foilline[$i]	if $entry==7;
		#
			}
		#
			$keeplinesperfoil[$foilset_ct][$foilno]= $ikeep;
			$keepmissingoption[$foilset_ct][$foilno]=$missingoption;
			print PERSTEMP "Endfoil:\n";
		#
		#	Set foil titles
			if($vocabref{"title"} >= 0)	{
				$foiltitle[$foilset_ct][$foilno]=$foilline[$vocabref{"title"}];
				$foiltitle[$foilset_ct][$foilno] =~ s/^\s*//;
				$foiltitle_html[$foilset_ct][$foilno]=$line_html[$vocabref{"title"}];
			}
			else	{
				$foiltitle[$foilset_ct][$foilno]="Title of foil ".$foilno;
				$foiltitle_html[$foilset_ct][$foilno]=0;
			}
		}
#
#	Now output foil to abstract file if appropriate
		next if( ($abstract_option <=0) || ($abstract_foil==0 && $foilno != $abstract_option) );
		$originalabsrawimage[$foilset_ct]='foil'.$abstract_option	unless( $abstract_foil==1 || $foilno!=$abstract_option || $originalabsrawimage[$foilset_ct] );
		$savehtmloption=$currenthtmloption;
		&outabstract(ABSTEMP);
		$currenthtmloption=$savehtmloption;
#
	}	# End loop over foils of this set on ORIGINAL
#
	close(ORIGINAL);
#
	$totalfoilcount[$foilset_ct]=$foilcount;	# Total number of foils
#
#	Set Best Url and best IMAGE
	$basedirectory = $currentdirectory . '/';
	$basedirectory = '' if($userelativefilenames == 1);
	for($i=1;$i<=$foilcount;$i++)	{
		unless( $wwwdir eq '.' || $wwwdir eq '' )	{
			$bestfoilurl[$foilset_ct][$i] = $wwwdir.'/fullindex.html#local'.$i;
		}
		else	{
			$bestfoilurl[$foilset_ct][$i]='fullindex.html#local'.$i;
		}
	}
#
#	$absrawimage defined later in &procwww as link not yet set in general
#	$imagestem = &getimagetype(  'seporgimagedir/abstract');
#	$absrawimage[$foilset_ct]=$wwwdir.'/seporgimagedir/abstract' . $imagestem;
        unless( $wwwdir eq '.' || $wwwdir eq '' )       {
                $bestabsurl[$foilset_ct]=$wwwdir.'/fullindex.html#localabstract';
                $bestfoilseturl[$foilset_ct]=$wwwdir.'/fullindex.html';
        }
        else    {
                $bestabsurl[$foilset_ct]='fullindex.html#localabstract';
                $bestfoilseturl[$foilset_ct]='fullindex.html';
        }
	$bestfoilurl[$foilset_ct][0]=$bestabsurl[$foilset_ct];
	$persoptions{"bestfoilseturl"}=$bestfoilseturl[$foilset_ct] unless $persoptions{"bestfoilseturl"};
	$bestfoilseturl[$foilset_ct]=$persoptions{"bestfoilseturl"};
#
#	Save overall options
	$persoptions{"author"}="Geoffrey C. Fox" unless($persoptions{"author"});
	$persoptions{"titleset"} =~ s/^\s*//;
	foreach $mem ("author","date","datemod","event","name","label","source","runningtitle","titleset","signature","bulletsongif","bestfoilseturl")	{
		next unless($persoptions{$mem});
		$keepoptions[$foilset_ct]{$mem}=$persoptions{$mem};
                $keepoptions_html[$foilset_ct]{$mem}=$options_html{$mem};
        }
#
#       Set abstract title
        if($persoptions{"runningtitle"})        {
		$trailer=$persoptions{"runningtitle"};
		$abstracttitle_html[$foilset_ct]=$options_html{"runningtitle"};
	}
	else	{
		$trailer="Presentation";
		$abstracttitle_html[$foilset_ct]=0;
	}
	$abstracttitle[$foilset_ct]="Abstract of " . $trailer;
#
#	Output Full Information
	if($processed)	{
		open(PROCESSED,"+>".$processed) || die("\nSorry couldnt Create Processed ",$processed, "\n");
		print PROCESSED "Endhtml:\n";
#
#	First Overall options
		foreach $mem ("author","date","datemod","event","name","label","source","runningtitle","titleset","signature")	{
			next unless($persoptions{$mem});
			&outdata( "\u${mem}:" . $persoptions{$mem} , $options_html{$mem}, PROCESSED);
		}
#
# Now append rest of information
		seek ABSTEMP,0,0;
		while( $line=<ABSTEMP> )	{
			print PROCESSED $line;
		}
		seek PERSTEMP,0,0;
		while( $line=<PERSTEMP> )	{
			print PROCESSED $line;
		}
		close PROCESSED;
	}	# End setting PROCESSED
	return;
#
}	# End Control_readfoil
#
#
#	Read a single foil or Abstract -- called from control_readfoil
# define $foilcount=0 $start=0 at beginning of file
sub readfoil{ # read a single foil -- $pendingreadfoil must defined as current line (or null)
#
	@bullet_number= (100,101,102,103,104,105,106,107,108,109);
#
	my($inhandle)= @_;
	my($char,$oldlevel,$i,$entry,$beginend,$begun,$level,$ct,$first,$rest);
#
	$curline = -1;	# storage position of current line -- used outside readfoil 
#			as one less than number of lines read for this foil
	$oldlevel=-1;	# type of last bullet seen
	$beginend=0;	# If nonzero, we are in beginfoil: endfoil: set
	$begun=0;	# If nonzero, foil has defintely begun
	$maybeended=0;	# Blank line detected -- maybe foil ended if $maybeended=1
	$abstract=0;	# If nonzero generate abstract from this foil
#
	$setcriticalmissing=0;	# If nonzero, generate  Critical Missing message
	$setsomemissing=0;	# If nonzero, generate Some missing message
	$setseealso=0;	# If nonzero, generate Seealso message
	$setnoimageversion=0;	# If nonzero, generate No IMAGE message
#
# Set reference point for all in vocab plus title and beginfoil
	foreach $vocabmem (keys %procoptvocab)	{
		$vocabref{$vocabmem} = -1;
	}
	$vocabref{"title"} = -1;
	$vocabref{"beginfoil"} = -1;
#
# Loop over input lines
	while (  $pendingreadfoil || ($pendingreadfoil=<$inhandle>) )	{
		$line=$pendingreadfoil;$pendingreadfoil="";
		chomp($line);
		unless($line)	{  # Empty Line
			next if( $beginend ) ;
			next if($curline == -1);
			$maybeended=1;
			next;
		}	# End empty line
#
		if ( $line =~ /^\S/ )	{ # Case when non blank character in column 1
			$maybeended=0;
			if( ($colon=index($line,":")) < 0 )	{
POSSIBLESTART:
				goto POWERPOINT if($powerpoint);
				die("\nIllegal Line ",$line,"\n") if($start);
				$foilline[++$curline] = $line;
				$linetype[$curline] = $bullet_number[0];
				$line_html[$curline] = $html;
				$vocabref{"runningtitle"}=$curline;
				$entry=100;
				next;
			} # End case no colon when nonblank in column 1
#
#   Case where colon detected
#
			$possiblekey = substr($line ,0, $colon);
			$possiblekey =~ s/\s+//g;
			$savekey=$possiblekey;
			$possiblekey =~ tr/A-Z/a-z/;
			$entry = -1;
			foreach  $vocabmem (keys %datavocab) {
				if( $possiblekey eq $vocabmem )	{
					$entry = $datavocab{$vocabmem};
					last;
				}
			}
			if( $entry < 0 )	{
				goto POSSIBLESTART;	}	
			$start=1;
			$rest = substr($line, $colon+1);
			if( $possiblekey eq "contd" )	{
				if ($curline ==  -1 )	{
					die("\nIllegal Continuation Line", $rest,"\n");	}
				if( $savekey eq "CONTD" ) 	{
				$foilline[$curline] .= "\n" . $rest;
				next;
				}
				$foilline[$curline]= &join($foilline[$curline],$rest);
				next;
			}
#
#  Test if Title or Running Title which need special attention
			if( $entry == 100 )	{  # Running Title
				if( $vocabref{"runningtitle"} >= 0 )	{ # Already started
					$foilline[$vocabref{"runningtitle"}] .= "\n" . $rest;
					next;
				}
				$oldlevel=0;
				$foilline[++$curline] = $rest;
				$linetype[$curline] = $entry;
				$line_html[$curline] = $html;
				$vocabref{"runningtitle"} = $curline;
				next;
			}
			if( $entry == 101 )	{   # Title
				if( $vocabref{"title"} >= 0 )	{ # Already started
					$foilline[$vocabref{"title"}] .= "\n" . $rest;
					next;
				}
				$oldlevel=1;
				$foilline[++$curline] = $rest;
				$linetype[$curline] = $entry;
				$line_html[$curline] = $html;
				$vocabref{"title"} = $curline;
				++$foilcount unless($begun);
				$begun=1;
				next;
			}
#
			if($entry==23)	{
				$html=0;
				next;
			}
			if($entry==25)	{
				$html=1;
				next;
			}
			$foilline[++$curline] = $rest;
			$linetype[$curline] = $entry;
			$line_html[$curline] = $html;
			if( $entry > 101 && $entry < 110 )	{ # Bullet
				$oldlevel=$entry-100;
				++$foilcount unless($begun);
				$begun=1;
				next;
			}
#
			if( $entry == 51 )	{   # Endfoil
				last;	# End of foil processing
			}
#
			if( $entry == 1 )	{  # Beginfoil
				die("\nIllegal Beginfoil: ",$rest,"\n") if( $beginend !=0 || $begun !=0 );
				++$foilcount;
				$begun=$beginend=1;
				$vocabref{"beginfoil"}=$curline;
				next;
			}
#
			if( $entry == 2 )	{  #    Image Location
				++$foilcount unless($begun);
				$begun=1;
				next;
			}
#
			if( $entry >=3 && $entry <=6 )	{
				die("\nIllegal foil comment ",$line, " \n")	unless($begun);
			}
#
			$setcriticalmissing=1	if( $entry == 3 )  ; # Critical Missing
			$setsomemissing=1	if( $entry == 4 ) ; # Some missing
			$setnoimageversion=1	if( $entry == 5 )  ; # No IMAGE
			$setseealso=1	if( $entry == 6 ) ; # Seealso
			next	if($entry <= 6 ) ;
#
			$vocabref{$possiblekey} = $curline	if( $entry==21 || $entry==24 || ($entry >= 26 && $entry <= 32 )  )	;
#
			$abstract=1 if( $entry == 22 )	;
			next;
		} # end case when nonzero character in column 1
#
#	Powerpoint Processing to see if bullet
POWERPOINT:
		if($powerpoint)	{
			$level=0;
			for($i=0;$i<5;$i++)	{
				$char= "\\" . $ppbullets[$i];
				if($line =~ /(^\s*)($char)(\s*)(.*)/)	{
					$level=2+$i;
					$rest=$4;
					last;
				}
			}
			goto TITLEBULLET if($level>1);
		}
#
#	
#	Case when line starts with tab or blank (Persuasion)
#	or doesnt start with a magic bullet(Powerpoint)
		$line =~ /(^\s*)(.*)/;
		$rest=$2; $first=$1; $ct=0;
		unless($rest)	{
			next if $beginend;
			next if ($curline == -1);
			$maybeended=1;
			next;
		}
		$start=1;
		while($x=chop($first))	{ # Count tab equivalents
			if($x eq "\t")	{ $ct += $blank;	}
			else 	{ ++$ct;	}
		}
		if($powerpoint)	{
			if($ct <= $ppcontdlimit && $curline >=0 )	{ # Continuation found
				$foilline[$curline] = &join($foilline[$curline],$rest);
				next;
			}
			$level=1; # Title of foil if not continuation
		}
		else	{ # Persuasion counts tabs
			$level= int(($ct+ 0.5*$blank)/$blank);
			$level=4 if( $level > 4);
		}
#
#	Start of newfoil maybe found
		if($maybeended && ($level <=1) )	{
			$pendingreadfoil= $line . "\n";
			last;
		}
		$maybeended=0;
#
		if( $level == 0 )	{ 
			if( $curline == -1 )	{  #  Running Title (possibly)
				$line = $rest;
				goto POSSIBLESTART;	}
			else	{ # continuation
				$foilline[$curline] = &join($foilline[$curline],$rest);
				next;
			}
		} # End case $level is zero
#
# Title or Bullet Detected
TITLEBULLET:
		++$foilcount unless($begun);
		$begun=1;
		if( $level == 1 )	{ # should be part of foil title
			if( $oldlevel == 1 )	{ # add to previous title
				$foilline[$vocabref{"title"}] .= "\n" . $rest;
				next;
			}
			if( $oldlevel == -1)	{ # create foil title
				$oldlevel =1;
				$vocabref{"title"} = ++$curline;
				$linetype[$curline] = $bullet_number[1];
				$foilline[$curline] = $rest;
				$line_html[$curline]=$html;
				next;
			}
			if( $beginend )	{ die("\nUnexpected title inside foil ",$line,"\n"); }
			$pendingreadfoil= $line. "\n"; # Must be start of next foil
			last;
		} # End case when part of foil title
#
#		Bullet as opposed to Title detected
#
		if( $level > 9 )	{
			die("\nUnreasonable Level ",$level,$line,"\n");
		}
		$oldlevel= $level;
		$foilline[++$curline]= $rest;
		$linetype[$curline] = $bullet_number[$oldlevel];
		$line_html[$curline] = $html;
		next;
#
	} # end loop over input lines for current foil
#
# Process Foil for abstract and full foil case
	foreach $mem ("author","date","datemod","event","runningtitle","name","label",
		"source","titleset","signature")	{
		next if $persoptions{$mem};
		next if ($vocabref{$mem} < 0);
		$persoptions{$mem} = $foilline[$vocabref{$mem}];
		$options_html{$mem} = $line_html[$vocabref{$mem}];
	}
#
	unless( $persoptions{"titleset"} )	{ # Titleset not set yet
		$prevtitle=$vocabref{"title"};
		if( ($prevtitle>=0) && ($foilcount==1) ) 	{
			$options_html{"titleset"}=$line_html[$prevtitle];
			$persoptions{"titleset"}=$foilline[$prevtitle];
		}
	}
#
# see if null foil
	$curline= -1 if($begun ==0);
	return if($curline == -1);
#
	if( ($prevbegin=$vocabref{"beginfoil"}) >= 0 )	{
		$colon=index($foilline[$prevbegin],":");
		$line=substr($foilline[$prevbegin],$colon+1);
		$line =~ s/\s*//;
		if($line)	{
			$slash=index($line,'/');
			if( $slash > -1 )	{
				$foilsource[$foilset_ct]=substr($line,0,$slash);
				$foilno=substr($line,$slash+1);
			}
			else	{
				if( &lcequal($line,'abstract'))	{
					$abstract=1;
					$foilno='Abstract';
					$foilsource[$foilset_ct]=$persoptions{"addsource"};
				}
				else	{
					$foilsource[$foilset_ct]=$line;
					$foilno=$foilcount;
				}
			}
		}
		else	{
			unless($abstract_reading)	{
				$foilno=$foilcount;
			}
			else	{
				$foilno='Abstract';
			}
			if( $persoptions{"addsource"} )	{
				$foilsource[$foilset_ct]=$persoptions{"addsource"};
			}
			else	{
				$foilsource[$foilset_ct]='Foilset '.$foilset_ct;
			}
		}
		$abstract=1 if &lcequal("Abstract",$foilno);
	}
	else	{	# No begin/endfoil commands this foil
		unless($abstract_reading)	{
			$foilno=$foilcount;
		}
		else	{
			$foilno='Abstract';
		}
		if( $persoptions{"addsource"} )	{
			$foilsource[$foilset_ct]=$persoptions{"addsource"};
		}
		else	{
			$foilsource[$foilset_ct]='Foilset '.$foilset_ct;
		}
	}
#
	$missingoption=0;
	$missingoption=1 if($setcriticalmissing==1)	;
	$missingoption=2 if($setsomemissing==1)	;
	$missingoption=3 if($setseealso==1)	;
	$missingoption=4 if( $setnoimageversion==1) ;
#	
	unless( $abstract_reading) {
		$test= &clean($foilno);
		if( ($missingoption==0) && ($line = $persoptions{"criticalmissing"}) )	{
			$line = &clean($line);
			$missingoption=1 if( $line =~ /$test/ );
		}
		if( ($missingoption==0) && ($line = $persoptions{"somemissing"}) )	{
			$line = &clean($line);
			$missingoption=2 if( $line =~ /$test/ );
		}
		if( ($missingoption==0) && ($line = $persoptions{"seealso"}) )	{
			$line = &clean($line);
			$missingoption=3 if( $line =~ /$test/ );
		}
		if( ($missingoption==0) && ($line = $persoptions{"noimageversion"}) )	{
			$line = &clean($line);
			$missingoption=4 if( $line =~ /$test/ );
		}
		if( ($missingoption==0) && ($line = $persoptions{"nogifversion"}) )	{
			$line = &clean($line);
			$missingoption=4 if( $line =~ /$test/ );
		}
	} # End Processing of Image Message if abstract
	$missingoption=3 if($missingoption==0) ;
	return;
#
} # end readfoil
#
#	Setup Audio Characteristics of foilset assuming these have been properly
#	preprocessed by setuprealaudio.pl which sets .rainfo files in audio.ra for all
#	single foilsets
sub setupfoilsetaudio	{
#
	my($foilset)=@_;
	my($foil,$localwwwdir,$source,$stem,$rainfo,$grab,$begingrab,$endgrab);
#
	$localwwwdir = $foilsetparms[$foilset]{"wwwdir"};
	$localwwwdir = '' if( $localwwwdir eq '.' );
#
#	Default to no audio
	$abstractaudioraurl[$foilset]='';
	$abstractaudioramurl[$foilset]='';
	$abstractaudiotime[$foilset]=0;
	$abstractaudionull[$foilset]=1;
	for($foil=1; $foil<=$totalfoilcount[$foilset]; $foil++ )	{
		$foilaudioraurl[$foilset][$foil]='';
		$foilaudioramurl[$foilset][$foil]='';
		$foilaudiotime[$foilset][$foil]=0;
		$foilaudionull[$foilset][$foil]=1;
	}
	$stem = '';
	$stem = $localwwwdir . '/' if( $localwwwdir );
	$source = $stem . 'audio.ra';
	return unless(-e $source);
	$source .= '/';
	$rainfo = $source . 'abstract.rainfo';
	if( -e $rainfo )	{
		open(RAINFO,'<'.$rainfo) || die("Sorry Could not open ",$rainfo," \n");
		while( $grab=<RAINFO> )	{
			$grab =~ m%([^:]*):(.*)$% ;
			$begingrab=$1;
			$endgrab=$2;
			$begingrab =~ tr/A-Z/a-z/;
			$abstractaudioraurl[$foilset]= $stem . $endgrab if( $begingrab eq 'raplace' );
			$abstractaudioramurl[$foilset]= $stem . $endgrab if( $begingrab eq 'ramplace' );
			$abstractaudiotime[$foilset]= $endgrab if( $begingrab eq 'seconds' );
			$abstractaudionull[$foilset]=0 if( ($begingrab eq 'nullaudio') && ( $endgrab eq 'no' ) );
		}
		close(RAINFO);
	}
	for($foil=1; $foil<=$totalfoilcount[$foilset]; $foil++ )        {
		$rainfo = $source . 'foil' . $foil . '.rainfo';
		next unless( -e $rainfo );
		open(RAINFO,'<'.$rainfo) || die("Sorry Could not open ",$rainfo," \n");
		while( $grab=<RAINFO> )	{
			$grab =~ m%([^:]*):(.*)$% ;
			$begingrab=$1;
			$endgrab=$2;
			$begingrab =~ tr/A-Z/a-z/;
			$foilaudioraurl[$foilset][$foil]= $stem . $endgrab if( $begingrab eq 'raplace' );
			$foilaudioramurl[$foilset][$foil]= $stem . $endgrab if( $begingrab eq 'ramplace' );
			$foilaudiotime[$foilset][$foil]= $endgrab if( $begingrab eq 'seconds' );
			$foilaudionull[$foilset][$foil]=0 if( ($begingrab eq 'nullaudio') && ( $endgrab eq 'no' ) );
		}
		close(RAINFO);
	}
#
}	# End setupfoilsetaudio
#
#
#	Setup Audio Characteristics of Script assuming these have been properly
#	preprocessed by setuprealaudio.pl which sets .rainfo files in audio.ra 
#	for those foils in script with new audio
#	Index of $scriptaudioraurl etc. starts at 1 not 0
#	If abstract or foil rainfo not set in audio.ra, we try to create from constituent foilset!
sub setupscriptaudio	{
#
	my($scriptpos,$masterset)=@_;
	my($foil,$localwwwdir,$source,$stem,$rainfo,$grab,$begingrab,$endgrab,$rapos,$rampos,$ramsource,$oldstem);
#
	$localwwwdir = $wwwdir;
	$localwwwdir = '' if( $localwwwdir eq '.' );
#
#	Default to no audio
	$scriptabstractaudioraurl='';
	$scriptabstractaudioramurl='';
	$scriptabstractaudiotime=0;
	$scriptabstractaudionull=1;
	for($foil=1; $foil<=$totalfoils_ct; $foil++ )	{
		$scriptaudioraurl[$foil]='';
		$scriptaudioramurl[$foil]='';
		$scriptaudiotime[$foil]=0;
		$scriptaudionull[$foil]=1;
	}
	$stem = '';
	$stem = $localwwwdir . '/' if( $localwwwdir );
	$source = $stem . 'audio.ra';
	unless(-e $source)	{
		mkdir($source,0755);
	}
	$ramsource = $source . 'm';
	unless(-e $ramsource)      {
		mkdir($ramsource,0755);
	}
	$source .= '/';
	$ramsource .= '/';
#
#	Set Foil audio
	for($foil=1; $foil<=$totalfoils_ct; $foil++ )        {
		$rainfo = $source . 'foil' . $foil . '.rainfo';
		unless( -e $rainfo )	{ # Create from Constituents
			$foilset = $listoffoilsets[$foil-1];
			$localfoil = $listoffoils[$foil-1];
			if( $foilaudioraurl[$foilset][$localfoil] )	{
				$rapos = $source . 'foil' . $foil . '.ra';
				$com='cp ' . $foilaudioraurl[$foilset][$localfoil] . ' ' . $rapos;
				system($com);
				$scriptaudioraurl[$foil]= $rapos;
			}
			if( $foilaudioramurl[$foilset][$localfoil] )     {
				$rampos = $ramsource . 'foil' . $foil . '.ram';
				$com='cp ' . $foilaudioramurl[$foilset][$localfoil] . ' ' . $rampos;
				system($com);
				$scriptaudioramurl[$foil]= $rampos;
			}
			$scriptaudiotime[$foil] = $foilaudiotime[$foilset][$localfoil];
			$scriptaudionull[$foil] = $foilaudionull[$foilset][$localfoil];
		}
		else	{		# Take what ever is set already
			open(RAINFO,'<'.$rainfo) || die("Sorry Could not open ",$rainfo," \n");
			while( $grab=<RAINFO> ) {
				$grab =~ m%([^:]*):(.*)$% ;
				$begingrab=$1;
				$endgrab=$2;
				$begingrab =~ tr/A-Z/a-z/;
				$scriptaudioraurl[$foil] = $stem . $endgrab if( $begingrab eq 'raplace' );
				$scriptaudioramurl[$foil] = $stem . $endgrab if( $begingrab eq 'ramplace' );
				$scriptaudiotime[$foil] = $endgrab if( $begingrab eq 'seconds' );
				$scriptaudionull[$foil] = 0 if( ($begingrab eq 'nullaudio') && ( $endgrab eq 'no' ) );
			}
		}

	}
#
#	Set Abstract Audio
	$rainfo = $source . '/abstract.rainfo';
	if( -e $rainfo )	{
		open(RAINFO,'<'.$rainfo) || die("Sorry Could not open ",$rainfo," \n");
		while( $grab=<RAINFO> )	{
			$grab =~ m%([^:]*):(.*)$% ;
			$begingrab=$1;
			$endgrab=$2;
			$begingrab =~ tr/A-Z/a-z/;
			$scriptabstractaudioraurl= $stem . $endgrab if( $begingrab eq 'raplace' );
			$scriptabstractaudioramurl= $stem . $endgrab if( $begingrab eq 'ramplace' );
			$scriptabstractaudiotime= $endgrab if( $begingrab eq 'seconds' );
			$scriptabstractaudionull=0 if( ($begingrab eq 'nullaudio') && ( $endgrab eq 'no' ) );
		}
		close(RAINFO);
	}
#
	else	{	# Try to Create Abstract Audio from master abstract
		if( $scriptpos eq 'masterabstract' )	{
			$oldstem = $foilsetparms[$masterset]{"wwwdir"} . '/';
			$rainfo = $oldstem . '/audio.ra/abstract.rainfo';
			if(-e $rainfo )	{
				open(RAINFO,'<'.$rainfo) || die("Sorry Could not open ",$rainfo," \n");
				while( $grab=<RAINFO> ) {
					$grab =~ m%([^:]*):(.*)$% ;
					$begingrab=$1;
					$endgrab=$2;
					$begingrab =~ tr/A-Z/a-z/;
					if( $begingrab eq 'raplace' )	{
						$rapos = $source . '/abstract.ra';
						$com='cp ' . $oldstem . $endgrab . ' ' . $rapos;
						system($com);
						$scriptabstractaudioraurl= $rapos;
					}
					if( $begingrab eq 'ramplace' )   {
						$rampos = $source . '/abstract.ram';
						$com='cp ' . $oldstem . $endgrab . ' ' . $rampos;
						system($com);
						$scriptabstractaudioramurl= $rampos;
					}
					$scriptabstractaudiotime= $endgrab if( $begingrab eq 'seconds' );
					$scriptabstractaudionull=0 if( ($begingrab eq 'nullaudio') && ( $endgrab eq 'no' ) );
				}
				close(RAINFO);
			}
		}
		else	{	# Try to Create Abstract Audio from Given Foil
			if( $scriptaudioraurl[$scriptpos] )	{
				$scriptabstractaudioraurl = $scriptaudioraurl[$scriptpos];
				$scriptabstractaudioramurl = $scriptaudioramurl[$scriptpos];
				$scriptabstractaudiotime = $scriptaudiotime[$scriptpos];
				$scriptabstractaudionull = $scriptaudionull[$scriptpos];
			}
		}
	}
#
}	# End setupscriptaudio
#
#	Return 0 if no audio and 1 if audio exists
#	Return Audio parameter in Display Parameter audioline for later use
sub setupaudioline	{
#
	my($inputoption)=@_;
	my($raurl,$ramurl,$audiotime,$audionull,$iconoffset,$audioline);
#
	if( $multi )	{	# Script to be accessed
		if( ($looptype == 1) || ($looptype == 2) )	{ # foilnumber in script
			$raurl = $scriptaudioraurl[$mixedfoilno];
			$ramurl = $scriptaudioramurl[$mixedfoilno];
			$audiotime = $scriptaudiotime[$mixedfoilno];
			$audionull = $scriptaudionull[$mixedfoilno];
		}
		else	{	# Abstract in Script
			$raurl = $scriptabstractaudioraurl;
			$ramurl = $scriptabstractaudioramurl;
			$audiotime = $scriptabstractaudiotime;
			$audionull = $scriptabstractaudionull;
		}
	}
	else	{	# Individual Foilset to be accessed
		if( ($looptype == 1) || ($looptype == 2) )      { # foilnumber in foilset
			$raurl = $foilaudioraurl[$currentfoilset][$currentfoilno];
			$ramurl = $foilaudioramurl[$currentfoilset][$currentfoilno];
			$audiotime = $foilaudiotime[$currentfoilset][$currentfoilno];
			$audionull = $foilaudionull[$currentfoilset][$currentfoilno];
		}
		else	{	# Abstract in Foilset
			$raurl = $abstractaudioraurl[$currentfoilset];
			$ramurl = $abstractaudioramurl[$currentfoilset];
			$audiotime = $abstractaudiotime[$currentfoilset];
			$audionull = $abstractaudionull[$currentfoilset];
		}
	}
	if( ($audionull != 0) || ($raurl eq '') )	{
		$valuewww{'audioline'}='';
		return 0;
	}
	$raurl = &jumpfoil($locpath,$raurl) if( $raurl );
	$ramurl = &jumpfoil($locpath,$ramurl) if( $ramurl );
	if( $inputoption eq 'audiobuttons' )	{
		$iconoffset = &jumpfoil($locpath,$filepath{'basedirectory'});
		$audioline='';
		if( $raurl )	{
			$audioline = '<a href="' .$raurl. '"><img align=top src="' .$iconoffset. 'icons/grey/audio.gif"></a>';
		}
		$audioline .= '<b>Secs '.$audiotime. '</b>';
		if( $ramurl )    {
			$audioline .= '<a href="' .$ramurl. '"><img align=top src="' .$iconoffset. 'icons/grey/audioserver.gif"></a>';
		}
	}
	else	{
		$audioline = $audiotime . ',' . $raurl . ',' . $ramurl;
	}
	$valuewww{'audioline'}=$audioline;
	return 1;
}	# End setupaudioline
#
#	Read in Templates defined in WWWTEMPLATE and write files
#	according to templates on directory $wwwdir
sub readwwwtemplate	{
#
	my($wwwtemplate)=$_[0];
	my($mode,$i);
#
	$newlinetobr=1;
	open(WWWTEMPLATE,"<".$wwwtemplate) || die("\nSorry couldnt Open ",$wwwtemplate, "\n");
	$currentfoilset=$masterfoilset;
	$wwwdir=$_[1];
	$wwwdirwritten=$_[2];
	$wwwdirwritten="." 	unless $wwwdirwritten;
	$modewww=0;
	$mode=0755;
	mkdir $wwwdirwritten,$mode	unless( defined(-e $wwwdirwritten));
	chdir $wwwdirwritten;
	$basedirectory=$currentdirectory.'/';
	$basedirectory = '' if($userelativefilenames == 1);
	$basedirectory .= $wwwdirwritten.'/' unless( $wwwdirwritten eq '.');
	undef %valuewww;
	undef %wwwalias_url;
	undef %wwwalias_title;
	undef %wwwalias_titlegiven;
	undef %wwwalias_comment;
	undef %wwwalias_author;
	undef %wwwalias_date;
	undef %wwwalias_url_used;
	&optwww;
	$setwwwref= -100001;
	for($i=0; $i<$totalscript_ct; $i++)	{
		$wwwscriptdone[$i]=0;
	}
	$wwwabstractdone=0;
	for($i=0; $i<$totalfoils_ct; $i++ )	{
		$wwwfoilsdone[$i]=0;
	}
	$wwwurlref=0;
	foreach $name (keys %wwwalias_url) {
		$wwwalias_url_used{$name}=0;
	}
	&alias_cleanup;
	seek WWWTEMPLATE,0,0;
	$modewww=1;
	&optwww;
	chdir $currentdirectory;
	$newlinetobr=0;
}	# End routine controlling processing of WWWTEMPLATE
#
sub alias_decode	{ # Decode alias definition
# key is EITHER in first argument or in first entry in value1@value2@  ..
# string transmitted as second argument
# if key is alias assume next entry in string is real key!
#
	my($key,$line)=@_;
	my(@fields,$test);
#
	@fields=split(/@/,$line);
	$test=$fields[0];
	$test =~ tr/A-Z/a-z/;
	shift(@fields)	if($test eq 'alias');
	$key=shift(@fields) unless $key;
	$key=shift(@fields) if $key eq 'alias';
#
	$wwwalias_url{$key}=$fields[0];
	if($fields[1])	{
		$wwwalias_title{$key}=&tohtml($fields[1]);
		$wwwalias_titlegiven{$key}=1;
	}
	else	{
		$wwwalias_title{$key}='At location ' . &tohtml($fields[0]);
		$wwwalias_titlegiven{$key}=0;
	}
	$wwwalias_comment{$key}= &tohtml($fields[2]);
	$wwwalias_author{$key}= &tohtml($fields[3]);
	$wwwalias_date{$key}= &tohtml($fields[4]);
#
}	# End alias_decode
#
sub alias_cleanup	{
#
	my($name,$replace);
#
	foreach $name (keys %wwwalias_url)	{
		$changed_alias=1;
		$replace=$wwwalias_url{$name};
		while( $changed_alias)	{
			$changed_alias=0;
			$replace=&alias_subst($replace);
		}
		$wwwalias_url{$name}=$replace;
	}
	foreach $name (keys %wwwalias_url)	{
		$wwwalias_url_used{$name}=0;
	}
}	# End alias_cleanup
#
sub alias_subst	{
#
	my($total);
#
	$end_alias=$_[0];
	$total="";
	while($end_alias)	{
		if(&aliascurlyscan($end_alias))	{
			$total .= $begin_alias;
			if( $full=$wwwalias_url{$tag_alias} )	{
				if( &aliasroundbracket($end_alias) )	{
					$string_alias=$wwwalias_title{$tag_alias} unless $string_alias;
					$total .= '<a href="' . $full . '" >' . $string_alias . '</a>';
				}
				else	{
					$total .= $full;
				}
				++$changed_alias;
				if( $setwwwref  != -100001 )	{
					++$wwwalias_url_used{$tag_alias};
					$foilreferenced[$wwwurlref]=$setwwwref;
					$tagreferenced[$wwwurlref]=$tag_alias;
					++$wwwurlref;
				}
			}
			else	{
				$total .= '{' . $tag_alias . '}';
			}
			next;
		}
		else	{
			$total .= $begin_alias;
			last;
		}
	}	# End loop over curly brackets
	return $total;
#
}	# End alias_subst
#
sub aliasroundbracket	{
#
	$end_alias=$_[0];
	if( $end_alias =~ m%^\\\(%	)	{
		$end_alias =~ s/^.//;
		return 0;
	}
	if( $end_alias =~ m%^\(([^\(\)]*)\)(.*)% )	{
		$string_alias= $1;
		$end_alias=$2;
		return 1;
	}
	return 0;
#
}	# End aliasroundbracket
#
sub aliascurlyscan	{ 
#
	my($inline)=@_;
	my($line);
#
	$line=$inline;
	$begin_alias='';
	while($line)	{
#
		if( $line =~ m%([^{]*){([^}]*)}(.*)% 	)	{
			if( $1 =~ m%\\$% )	{
				$begin_alias .= $1 . '{';
				$line = $2.'}'.$3;
				next;
			}
			$begin_alias .= $1;
			$end_alias=$3;
			$tag_alias=$2;
			$tag_alias =~ s/\s*//g;
			return 1;
		}
		$begin_alias=$inline;
		$end_alias='';
		$tag_alias='';
		return 0;
	}	# End loop over starting {
	$begin_alias=$inline;
	return 0;
#
}	# End alias curly scan
#
sub optwww	{
#
	my($perswwwkey,$restwww,$linewww,$readwwwline,$colonwww,$entrywww,$optmemwww,$possiblewwwkey,$actualwwwkey,$index,$lefttest,$test,$bladd,$len,$parms);
#
%optwww=
("mkfile",11,"mkdir",12,"cd..",13,"contd",10,"type",15,"template",16,
 "comment",17,"nickname",14,"absrawimage",0,"foilrawimage",0,"searchline",0,"titlesetsize",0,
 "runningtitle",0,"titleset",0,"protectedtitleset",0,"date",0,"label",0,"author",0,"bestfoilseturl",0,
 "datemod",0,"event",0,"signature",0,"source",0,"padlabel",0,"leftpadlabel",0,
 "foreign",0,"native",0,"bestfoilurl",0,"bestfoilseturl",0,"bestabsurl",0,"imagesize",0,"imagetype",0,
 "beginalias",101,"endalias",102,"aliasfile",101,
 "abstract/title",0,"abstract/protectedtitle",0,"abstract/bullet1",0,
 "abstract/bullet2",0,"abstract/bullet3",0,"abstract/htmlline",0,
 "script/title",0,"script/protectedtitle",0,"script/bullet1",0,
 "script/bullet2",0,"script/bullet3",0,"script/htmlline",0,
 "foil/title",0,"foil/protectedtitle",0,"foil/bullet1",0,
 "foil/bullet2",0,"foil/bullet3",0,"foil/htmlline",0,"missing",0,
 "nextlocal",0,"prevlocal",0,"nextlocal2",0,"prevlocal2",0,"missing2",0,
 "next",0,"prev",0,"next2",0,"prev2",0,"localfoil#",0,"extfoil#",0);
#
	$perswwwkey="NONE";
	$path="";
	$lastpath="NONE";
	$lastlabel='';
	$lasttemplate='';
	$lasttype='';
	$wwwalias_mode=0;
#
#	Set Padded Label and other processed Foilset Options
	for($index=0;$index<$totalfoilset_ct;$index++)	{
		$keepoptions[$index]{"protectedtitleset"}= &protectquote($keepoptions[$index]{"titleset"});
		$keepoptions_html[$index]{"protectedtitleset"} =0;
		$test=$keepoptions[$index]{"label"};
		$lefttest=$keepoptions[$index]{"label"};
		$len=length($test);
		for($bladd=$len;$bladd<$labellength;$bladd++)	{
			$test .= ' ';
			$lefttest = ' ' . $lefttest;
		}
		$keepoptions[$index]{"padlabel"}=$test;
		$keepoptions_html[$index]{"padlabel"}=0;
		$keepoptions[$index]{"leftpadlabel"}=$lefttest;
		$keepoptions_html[$index]{"leftpadlabel"}=0;
	}
#
#	Set up class 1 items with their allowed / prefixes
	for $optmemwww ("label","leftpadlabel","padlabel","author","date","datemod","event","source","runningtitle","titleset","titlesetsize","signature","bestfoilseturl","protectedtitleset")	{
		$classwww{$optmemwww}=1;
		$classwww{'mixed/'.$optmemwww}=1;
		$classwww{'local/'.$optmemwww}=1;
		for($index=0;$index<$totalfoilset_ct;$index++)	{
			$classwww{$foilsetparms[$index]{"name"}.'/'.$optmemwww}=1;
		}
	}
	$classwww{"readabstract"}=2;
	$classwww{"readfoil"}=3;
	$classwww{"missing"}=4;
	$classwww{"missing2"}=4;
	$classwww{"title"}=5;
	$classwww{"bullets"}=6;
	$classwww{"aliaslist"}=7;
	$classwww{"fullaliaslist"}=9;
	$classwww{"urlsonly"}=8;
	$classwww{"next"}=10;
	$classwww{"next2"}=10;
	$classwww{"besturl"}=11;
	$classwww{"prev"}=12;
	$classwww{"prev2"}=12;
	$classwww{"localfoil#"}=13;
	$classwww{"extfoil#"}=14;
	$classwww{"nextlocal"}=15;
	$classwww{"nextlocal2"}=15;
	$classwww{"prevlocal"}=16;
	$classwww{"prevlocal2"}=16;
	$classwww{"select"}=17;
	$classwww{"nobulletsifgif"}=18;
	$classwww{"nonewlines"}=19;
	$classwww{"loopfoils"}=21;
	$classwww{"loopscript"}=23;
	$classwww{"loopfoilset"}=24;
	$classwww{"endloop"}=22;
	$classwww{"today"}=31;
	$classwww{"prettyprint"}=32;
	$classwww{"usedfoilslist"}=33;
	$classwww{"sortedfoilslist"}=34;
	$classwww{"local"}=35;
	$classwww{"mixed"}=36;
	$classwww{"global"}=36;
	$classwww{"linesize"}=37;
	$classwww{"foreign"}=38;
	$classwww{"native"}=39;
	$classwww{"bestfoilurl"}=40;
	$classwww{"bestabsurl"}=41;
	$classwww{"foilrawimage"}=43;
	$classwww{"absrawimage"}=44;
	$classwww{"searchline"}=45;
	$classwww{"lastdirectory"}=46;
	$classwww{"wwwdir"}=47;
	$classwww{"target"}=48;
	$classwww{"titlesize"}=49;
	$classwww{"bullet1size"}=52;
	$classwww{"bullet2size"}=53;
	$classwww{"urlsonlysize"}=54;
	$classwww{"viewname"}=55;
	$classwww{"protectedtitle"}=56;
	$classwww{"imagesize"}=57;
	$classwww{"imagetype"}=58;
#
	for $parms (keys %displayparms)	{
		$classwww{$parms}=51;
		$optwww{$parms}=51;
	}
	$classwww{"selectbrowser"}=50;
#
	for $optmemwww (keys %optwww)	{
		$valuewww{$optmemwww}="NONE";
	}
#
	while( $linewww=<WWWTEMPLATE>)	{
		chomp($linewww);
		if($wwwalias_mode==1)	{
			$colonwww = index($linewww,"@");
			$colonwww = index($linewww,":") unless $colonwww;
		}
		else	{
			$colonwww = index($linewww,":");
		}
		if ( ($linewww =~ /^\S/) && $colonwww < 0 )	{
			die("\nIllegal Continuation Line", $restwww,"\n") if $perswwwkey eq "NONE";
			$linewww =~ s/^\s+/ /;
			$readwwwline = &join($readwwwline,$linewww);
			next;
		}
		$possiblewwwkey = substr($linewww ,0, $colonwww);
		$possiblewwwkey =~ s/\s+//g;
		$actualwwwkey=$possiblewwwkey;
		$possiblewwwkey =~ tr/A-Z/a-z/;
		$entrywww = -1;
		foreach  $optmemwww (keys %optwww) {
			if( $possiblewwwkey eq $optmemwww )	{
				$entrywww = 1;
				last;
			}
		}
		if( ($perswwwkey ne 'beginalias') && ($wwwalias_mode == 0) && ($entrywww < 0) )	{
			die("\nIllegal key WWWTemplate ", $possiblewwwkey, "\n");	}	
		$restwww = substr($linewww, $colonwww+1);
		$restwww =~ s/(\s)*//;
		if( $possiblewwwkey eq "contd" )	{
			die("\nIllegal Continuation Line", $restwww,"\n")	if ($perswwwkey eq 'NONE');
			$readwwwline = &join($readwwwline,$linewww);
			next;
		}
		else	{
			&procwww($readwwwline,$perswwwkey)	unless $perswwwkey eq 'NONE';
		}
		$readwwwline = $restwww;
		$perswwwkey =$possiblewwwkey;
		$perswwwkey_nolc=$actualwwwkey;
	}
	&procwww($readwwwline,$perswwwkey);
	return	if( $modewww == 0 );
	&printwww($lastlabel)	if( $lastlabel );
#
}	# End routine reading instructions controlling construction of WWW foil set
#
sub procwww	{
	my($fullline,$key)=@_;
	my($testprocwww,$mode,$newlink,$oldlink,$i,$index,$typewww);
#
%typewww=
("overall",1,"fullhtml",2,"sephtml",3,"sepimage",4,"seporgimagedir",5,"other",6,"directory",7,"sepabshtml",8,"sepabsimage",9,"mixedhtml",10,"sepmixed",11,"sepgif",4,"seporggifdir",5,"sepabsgif",9);
#
# Process Aliases
	if($wwwalias_mode && ($key ne 'endalias') )	{
		return if $modewww;
		&alias_decode($perswwwkey_nolc,$fullline);
		return;
	}
	$testprocwww=$optwww{$key};
	if( $testprocwww == 101 )	{
		unless($fullline)	{
			$wwwalias_mode=1;
			return;
		}
		return if $modewww;
		open(ALIAS,$fullline) || die("Sorry Couldnt read ALIAS ",$fullline," \n");
		while($fullline=<ALIAS>)	{
			chomp($fullline);
			&alias_decode('',$fullline);
		}
		close(ALIAS);
		$wwwalias_mode=0;
		return;
	}
	if( $testprocwww == 102 )	{
		$wwwalias_mode=0;
		return;
	}
#
	$valuewww{$key}=$fullline;
	return if( $testprocwww <= 10 );
	return if( $testprocwww == 17 );
	return if( $testprocwww == 51 );
#
	if( $testprocwww >= 11 && $testprocwww <= 13 )	{	# set up next file
		&printwww($lastlabel)	if( $lastlabel && ($modewww==1) );
		$lastlabel='';
		$lasttype='';
		$lasttemplate='';
	}
#
	if( $testprocwww == 11 )	{ # New file defined
		if( $fullline =~ m%^/% )	{
			$lastpath=$fullline;
		}
		else	{
			if($path)	{
				$lastpath=$path.'/'.$fullline;
			}
			else { $lastpath=$fullline;	};
		}
		return;
	}
#
	if( $testprocwww == 12 )	{	# Directory set
		if( $fullline eq '$HOME' || $fullline eq '' )	{
			$path="";
			$lastpath='/';
			return;
		}
		$fullline =~ s%/$%% ;	# Remove trailing /
		if( $fullline =~ m%^/%	)	{ 	# Absolute address
			$path=$fullline;
			$lastpath=$path.'/';
			return;
		}
		else	{ 	# Relative address
			if( $path)	{
				$path .= '/'.$fullline;
			}
			else	{ 
				$path=$fullline; 
				$lastpath= $path.'/';
			}
		}
		return if $modewww==1;
		$createfile = $path;
		return if( defined(-e $createfile) );
		$mode=0755;
		mkdir $createfile,$mode;
		return;
	}
#
	if( $testprocwww == 13 )	{	# cd..
		if( $path )	{ # Path exists already
			$path='' unless $path =~ s%/[^/]+$%% ;
		}
		else	{
			$path = ".."
		}
		$lastpath=$path.'/';
		return;
	}
#
	if( $testprocwww == 15 )	{	# type defined
		$fullline =~ tr/A-Z/a-z/;
		die "Illegal Type ",$fullline,"\n"	unless $typewww{$fullline};
		$lasttype=$typewww{$fullline};
		return if $modewww==1;
		if( $lastlabel )	{
			die "Duplicate Type",$lasttype,"\n" if( $filetype{"lastlabel"} );
			$filetype{"lastlabel"}=$lasttype;
		}
		return;
	}
#
	if( $testprocwww == 16 )	{	# template defined
		$lasttemplate=$fullline;
		return if $modewww==1;
		if( $lastlabel )	{
			die "Duplicate Type",$lasttemplate,"\n" if( $filetemplate{"lastlabel"} );
			$filetemplate{"lastlabel"}=$lasttemplate;
		}
		return;
	}
#
	if( $testprocwww == 14 )	{ 	# Label defined
		die "No file defined for label ",$fullline,"\n" if( $lastpath eq "NONE" );
		$lastlabel=$fullline;
		return if $modewww==1;
#
		$classwww{$lastlabel}=11;
		$classwww{'mixed/'.$lastlabel}=11;
		$classwww{'local/'.$lastlabel}=11;
		for($index=0;$index<$totalfoilset_ct;$index++)	{
			$classwww{$foilsetparms[$index]{"name"}.'/'.$lastlabel}=11;
		}
#
		$filepath{$lastlabel}=$lastpath;
		$filetype{$lastlabel}=$lasttype 	if( $lasttype );
		$filetemplate{$lastlabel}=$lasttemplate 	if( $lasttemplate );
#
#	Set up abstract IMAGE symbolic links correctly for single foilsets
		return if( $lasttype != 5) ;
		return if $multi;
		setrawimage($currentfoilset);
		return;
	}
#
}	# End routine processing lines of information
#
sub setrawimage	{
#
my($thisfoilset) =@_;
my($abstest,$imagestem,$absnum,$oldlink,$newlink,$i);
#
	$abstest= $originalabsrawimage[$thisfoilset];
	$abstest =~ s%\s*$%%;
	$originalabsrawimage[$thisfoilset] = $abstest;
	unless($abstest)	{
		$keepabsmissingoption[$thisfoilset]=4;
		$absrawimage[$thisfoilset] = '';
	}
	else	{
		$abstest =~ s/(\d*)$//;
		$absnum=$1;
		if( $abstest eq 'foil' )	{
			$absnum =  &externalnumericlabel($absnum);
			$oldlink = $basedirectory . $path.'/'.$absnum;
			$imagestem = getimagetype($oldlink);
			unless($userelativefilenames)	{
				$oldlink .= $imagestem;
			}
			else	{ # Relative filenames
				$oldlink = $absnum . $imagestem;
			}
		}
		else	{
			$imagestem = $originalabsrawimage[$thisfoilset];
			$imagestem =~ m%\.(\D*)$%;
			$imagestem = '.' . $1;
			$oldlink=&absolutefile($originalabsrawimage[$thisfoilset]);
			$oldlink = &jumpfoil($newlink,$oldlink) if($userelativefilenames);
		}
		$newlink= $basedirectory . $path . '/abstract';
		$newlink .= $imagestem;
		unless( defined(-e $newlink) || (-l $newlink) )	{ # Should try to create abstract link
			symlink $oldlink,$newlink;
		}
		unless( defined(-e $newlink) || (-l $newlink) )	{
			$keepabsmissingoption[$thisfoilset]=4;
			$absrawimage[$thisfoilset] = '';
		}
		else	{
			$absrawimage[$thisfoilset] = $path . '/abstract'. $imagestem;
		}
	}
#
#	Set IMAGE Symbolic Links for single foilsets foils whose IMAGE location set by getimagefrom
#	Set $foilrawimage for all single foilsets
	for($i=1;$i<=$totalfoilcount[$thisfoilset];$i++)	{
		unless($originalfoilrawimage[$thisfoilset][$i] eq '')	{
			$imagestem = $originalfoilrawimage[$thisfoilset][$i];
			$imagestem =~ s%\s*$%%;
			$originalfoilrawimage[$thisfoilset][$i] = $imagestem;
			$imagestem =~ m%\.([^\.]*)$%;
			$imagestem = '.' . $1;
			$newlink= $basedirectory . $path.'/'.(&externalnumericlabel($i)).$imagestem;
			unless( defined(-e $newlink) || (-l $newlink) )	{
				$oldlink= &absolutefile($originalfoilrawimage[$thisfoilset][$i]);
				$oldlink = &jumpfoil($newlink,$oldlink) if($userelativefilenames);
		     		symlink $oldlink,$newlink;
			}
			$foilrawimage[$thisfoilset][$i] = $path.'/'.(&externalnumericlabel($i)).$imagestem;
		}
		elsif( $keepmissingoption[$thisfoilset][$i] == 4 )	{
			$foilrawimage[$thisfoilset][$i] = '';
		}
		else	{
			$imagestem = $path.'/'.(&externalnumericlabel($i));
			$foilrawimage[$thisfoilset][$i] = $imagestem .  (&getimagetype($imagestem));
		}
	}	# End loop over foils
	return;
#
}	# End setrawimage
#
sub absolutefile	{ # Get correct absolute file address
#
	my($file)=@_;
#
	$file =~s%\s*%%g;
	if(($file =~ m%^\/%) || ($file =~ m%^http%) )	{
		return $file;
	}
	$file = $basedirectory . $file;
#
}	#	End absolutefile
#
sub getimagetype	{ # Get extension of given file
#
	my($stem)=@_;
	my($full,$match);
#
#	Note must use ($match) else every other glob wrong -- see PERLOP manual page ...
	$full = &absolutefile($stem);
	($match) = <$full*>;
	if(defined($match))	{
		$match =~ m%^$full(.*)%;
		return $1;
	}
	print('Warning missing image file ',$stem," globbed\n");
	return 'MISSINGimageFILE';
#
}	# End getimagetype
#
sub printwww	{	# Actually write out files from templates
#	Key Pointers
#	$globalfoilsettype	if -1 use mixed labelling
#				if n(>=0) use n'th foilset
#	$currentfoilset		Current foilset of current foil
#	$currentfoilno		Number of current foil within ITS OWN foilset
#	$mixedfoilno		Number within mixed foilset
#	$multi			if 0 single foilset, 1 if multiple
#	$looptype		1 foils * 2 script * 3 foilset
#
	my($relfile,$i,$j,$temp,$loop,$lasti,$writefile,$testwww,$lastdir,$shortname,@list,@sortedlist);
	$loclabel=$_[0];
#
	$loctype=$filetype{$loclabel};
	return if( ($loctype >= 5)&&($loctype<=7) );
	$locpath=$filepath{$loclabel};
	$loctemplate=$filetemplate{$loclabel};
	die "Illegal path",$locpath,"\n" unless($locpath);
	die "Illegal type",$loctype,"\n" unless($loctype);
	die "Illegal template",$loctemplate,"\n" unless($loctemplate);
#
	$nobulletsifgif=0;
	$nonewlines=0;
	open(TEMPLATE,"<".$loctemplate) || die("Sorry couldn't create ",$loctemplate,"\n");
	@template = <TEMPLATE>;
	if( ($loctype <= 2) || (($loctype>=8) && ($loctype <= 10)) ) 	{
		open(CURFILE,">".$locpath) || die("\nSorry couldn't create ",$locpath,"\n");
	}
	$outcontd=0;
	$nocol=0;
	$linect=0;
	$lasti=@template;
	$abstract=-1;
	$currentfoilset=$masterfoilset;
	$looptype=0;
	$setwwwref= -100001;
	$prettyprint=0;
	$oldprettyprint=0;
	$linesize=80;
	$targetreplace=0;
	$targetframe="foil";
#
PRINTWWW1:
	for($i=0; $i < $lasti ; $i++)	{
	$looping=0;
	$finishedscript=0;
	$currentmaxfoilno=$totalfoils_ct;
	$mixedfoilno=0;
#
PRINTWWW2:
		for($loop=$i; $loop < $lasti ; $loop++)	{
			$end=$template[$loop];
			chomp($end);
			$prettyprint=0;
			$lineacc='';
			$globalfoilsettype=-1;
			$globalfoilsettype=$currentfoilset if $looptype == 3;
			while($end)	{
				if( &curlyscan($end) )	{
					$lineacc .= $begin;
					$testwww=$classwww{$tag};
#
#	Set loops over foils, foilsets, scripts
					if( $testwww==21 )	{ 	# Begin loop over foils
						&run_loopfoils;
						next PRINTWWW2;
					}
					if( $testwww==23 )	{ 	# Begin loop over script
						&run_loopscript;
						next PRINTWWW2;
					}
					if( $testwww==24 )	{ 	# Begin loop over foilsets
						&run_loopfoilset;
						next PRINTWWW2;
					}
					if( $testwww==22 )	{	# End loop
						goto PRINTWWW2 if( ($looping < $loopsize) && $finishedscript==0 );
						$i=$loop;
						$looptype=0;
						close(CURFILE) if( $loctype == 3 || $loctype == 4 || $loctype == 11 );
						$currentfoilset=$masterfoilset;
						$globalfoilsettype= -1;
						$setwwwref= -100001;
						next PRINTWWW1;
					}
					next PRINTWWW2 if $finishedscript;
#
#	Nonloop options
					if( $testwww == 38 )	{
						next PRINTWWW2 unless $foilsetparms[$currentfoilset]{"foreign"};
					}
					if( $testwww == 39 )	{
						next PRINTWWW2 if $foilsetparms[$currentfoilset]{"foreign"};
					}
					if( $testwww == 40 )	{ # Best foil URL
						$relfile= &jumpfoil($locpath,$bestfoilurl[$currentfoilset][$currentfoilno]);
						$lineacc .= $relfile;
					}
					if( $testwww == 41 )	{ # Best abstract URL
						$relfile= &jumpfoil($locpath,$bestabsurl[$currentfoilset]);
						$lineacc .= $relfile;
					}
					if( $testwww == 43 )    { # Best Foil IMAGE
						if( $multi)	{ # Scripted Image
							$relfile= &jumpfoil($locpath,$scriptrawimage[$mixedfoilno]);
						}
						else	{	# Foil image
							$relfile= &jumpfoil($locpath,$foilrawimage[$currentfoilset][$currentfoilno]);
						}
						$lineacc .= $relfile;
					}
					if( $testwww == 44 )	{ # Best Abstract IMAGE
						if( ($globalfoilsettype == -1) && $multi )	{ # Script abstract
							$relfile= &jumpfoil($locpath,$scriptabsrawimage);
						}
						else	{
							$relfile= &jumpfoil($locpath,$absrawimage[$currentfoilset]);
						}
						$lineacc .= $relfile;
					}
					&setimagesize(0)	if($testwww == 57 );
					&setimagesize(1)	if($testwww == 58 );
					if( $testwww == 48 )	{ # Toggle for adding target info
						$targetreplace = 1 - $targetreplace;
						$targetframe = $tagvalue;
					}
					&maketitlesize()	if( $testwww == 49 );  # Set Title Size
					&makebullet1size(0)	if( $testwww == 52 );  # Set Bullet1 Size
					&makebullet2size(0)	if( $testwww == 53 );  # Set Bullet2 Size
					&makebullet1size(1)     if( $testwww == 54 );  # Set UrlsOnly Size
					$lineacc .= &makeviewname($tagvalue)	if( $testwww == 55 ); # set view name
#
					&searchline($mixedfoilno,$tagvalue) if( $testwww == 45 );	# Set magic clicking line
#
#	Display attributes
					if( $testwww == 51)	{
						if( $tagvalue)	{
							$valuewww{$tag}=$tagvalue;
						}
						else	{
							&makeglobalitem($tag);
						}
					}
					if( $testwww == 50 )	{
						unless( ($tagvalue eq $displayparms{"browser"}))	{
							next PRINTWWW2  if($looping);
							last PRINTWWW2  unless($looping);
						}
					}
#
#	Set printing line specifying directory
					if( $testwww == 46 ) 	{ # directory
						$lastdir = `pwd`;
						chomp($lastdir);
						$lastdir =~ m%/([^/]*)$%;
						$lastdir =$1;
						$lineacc .= $lastdir;
					}
					if( $testwww == 47 )    { # Directory Name for Component
						$shortname = $foilsetparms[$currentfoilset]{"wwwdir"};
						$shortname =~ s%/%%g;
						$shortname =~ s%\.%%g;
						$lineacc .= $shortname;
					}
					$globalfoilsettype=$currentfoilset if $testwww==35;
					$globalfoilsettype=-1 if $testwww==36;
					$lineacc .= $today if $testwww==31;
					if( $testwww==32 )	{ # Prettyprint set up
						$prettyprint=1;
						if( $tagvalue > 0 )	{
							$prettyskip=$tagvalue+$labellength;
						}
						else	{
							$prettyskip = -$tagvalue;
						}
						$prettyout= '';
						for($j=0;$j<$prettyskip;$j++)	{
							$prettyout .= ' ';
						}
					}
					$lineacc .= $foilsetparms[$currentfoilset]{"usedfoilslist"} if $testwww==33;
					if( $testwww==34 )	{
						@list=split(' ',$foilsetparms[$currentfoilset]{"usedfoilslist"});
						@sortedlist=sort { $a <=> $b; } @list;
						$lineacc .= join(' ',@sortedlist);
					}
					$linesize=$tagvalue if $testwww==37;
#
					&makeitem($tag) if $testwww==1;
					&makeabstract if $testwww==2;
					&makefoil(0) if $testwww==3;
					if( $testwww==4 )	{
						last if &makemissing($tag);
					}
					&maketitle if $testwww==5;
					&makeprotectedtitle if $testwww==56;
					&makefile($tag) if $testwww==11;
					&makebullets(0) if $testwww==6;
					&makealiaslist($testwww) if($testwww==7 || $testwww==9);
					&makebullets(1) if $testwww==8;
					&makeref($tag,1) if $testwww==10;
					&makelocalref($tag,1) if $testwww==15;
					&makeref($tag,-1) if $testwww==12;
					&makelocalref($tag,-1) if $testwww==16;
					&makefoilnum if $testwww==13;
					&makepadfoilnum if $testwww==14;
					if( $testwww==17 && ($tagvalue =~ m%^audio%) )	{
						last unless &setupaudioline($tagvalue);
						next;
					}
					if( $testwww==17 && $tagvalue<10 )	{	# select on missingoption
						last unless ($missingoption==$tagvalue) ;
					}
					if( $testwww==17 && $tagvalue==12 )      {       # select several missing options
						last if ($missingoption==4||$missingoption==3) ;
					}
					if( $testwww==17 && $tagvalue==123 )	{
						last if ($missingoption==4);
					}
					if( $testwww==17 && $tagvalue==34 )	{
						last if ($missingoption==1||$missingoption==2) ;
					}

					if( $testwww==18 )	{ # nobulletsifgif
						$nobulletsifgif=1;
					}
					$nonewlines=1 if $testwww==19;
				}
				else	{
					$lineacc .= $begin;
					last;
				}
			}
			&outacc;
			&foilflush(CURFILE);
			last PRINTWWW2 unless $looping;
		}
	}
	close(CURFILE) if $loctype <=2;
	close(CURFILE) if (($loctype>=8) && ($loctype<=10));
	close(TEMPLATE);
#
}	# End routine printing from template
#
#	Control loop over foils
sub run_loopfoils	{
#
	my($temp);
#
	$loopsize=$totalfoils_ct;
	$currentmaxfoilno=$loopsize;
	$currentfoilset=$listoffoilsets[$looping];
	$currentfoilno=$listoffoils[$looping];
	++$looping;
	$mixedfoilno=$looping;
	$globalfoilsettype= -1;
	$looptype=1;
	$abstract=0;
	if( $loctype ==3 || $loctype == 4 || $loctype == 11 ) 	{
		$temp= (&externalnumericlabel($looping));
		$writefile = $locpath;
		$writefile =~ m%(^.*/)([^/]*)$%;
		$writefile = $1. $temp .$2;
		open(CURFILE,">".$writefile) || die("\nSorry couldn't create ",$writefile,"\n");
	}
}	# End run_loopfoils
#
#	Control loop over script lines
sub run_loopscript	{
#
	my($type,$index,$bullet,$header,$entry,$label,$run,$level);
#
	die("Illegal use of loopscript in separate file option ",$loctype,"\n")	if( $loctype ==3 || $loctype == 4 || $loctype == 11 );
	$loopsize=$totalscript_ct;
	$currentmaxfoilno=$totalfoils_ct;
	$looptype=2;
	$bullet=0;
	$header='script/';
	&outacc;
#
	while(){	# Loop over script lines
		$setwwwref= -100001;
		if ( ($looping >= $loopsize) || (($type=$typeofscriptline[$looping]) == -1) ) {
			for($run=0;$run<$bullet;$run++)	{
				&foillineout("</ul>",1,CURFILE);
				&foilflush(CURFILE);
			}
			if($looping >= $loopsize) 	{
				$finishedscript=1;
				return;
			}
			elsif	( $type == -1)	{
				last;
			}
		}
		$setwwwref= -1-$looping	unless $wwwscriptdone[$looping];
		$index=$indexofscriptline[$looping];
		$entry=$script_type[$index];
		if($entry == 100 )	{ #HTMLline
			&foilflush(CURFILE);
			&foillineout('<a name="localscriptline'.$looping.'"> </a>',1,CURFILE);
			&sandwich($script_list[$index],1,$valuewww{$header.'htmlline'});
			&outacc;
			++$looping;
			next;
		}
		$label="title" if $entry==101;
		$label="bullet1" if $entry==102;
		$label="bullet2" if $entry==103;
		$label="bullet3" if $entry>=104;
		$label= $header.$label;
		$level=$entry-101;
		if($level > $bullet)	{
			for($run=0;$run<$level-$bullet;$run++)	{
				&foillineout("<ul>",1,CURFILE);
				&foilflush(CURFILE);
			}
		}
		if($level < $bullet)	{
			for($run=0;$run<$bullet-$level;$run++)	{
				&foillineout("</ul>",1,CURFILE);
				&foilflush(CURFILE);
			}
		}
		$lineacc="<li>"	unless $entry == 101;
			&foilflush(CURFILE);
			&foillineout('<a name="localscriptline'.$looping.'"> </a>',1,CURFILE);
		&sandwich($script_list[$index],$script_html[$index],$valuewww{$label});
		&outacc;
		$bullet=$level;
		++$looping;
#
	}	# End while over non foil entries in script lines
#
#	New foil to be set up
	$mixedfoilno=$indexofscriptline[$looping];
	$looping++;
	$currentfoilset=$listoffoilsets[$mixedfoilno];
	$currentfoilno=$listoffoils[$mixedfoilno];
	++$mixedfoilno;
	$globalfoilsettype= -1;
	$abstract=0;
	return 0;
#
}	# End run_loopscript
#
#	Control loop over foilsets
sub run_loopfoilset	{
#
	$loopsize=$usedfoilset_ct;
	$currentfoilset=$usedfoilsets[$looping];
	$looptype=3;
	$globalfoilsettype=$currentfoilset;
	++$looping;
#
}	# End run_loopfoilset controlling loop over foilsets
#
sub outacc	{ # Output Line accumulator
#
	my($save,$result);
#
	if( $lineacc )	{
		&foilflush(CURFILE);
		$save=$linesize;
		$linesize=500 unless $prettyprint;
		$result = &alias_subst($lineacc);
		if($targetreplace)	{
			$result =~ s%href=%YUCKYYUCKY%ig;
			$result =~ s%(<[^>]*target=[^>]*)YUCKYYUCKY%$1href=%ig;
			$result =~ s%YUCKYYUCKY%target="${targetframe}" href=%g;
			}
		&foillineout( $result,1,CURFILE);
		$linesize=$save;
		&foilflush(CURFILE);
		$lineacc='';
	}
#
}	# End outacc
#
sub makeitem { # Output a simple item held in $item
#
	my($item)=@_;
	my($out,$out_html,$saveline);
#
	($globalfoilsettype,$item)= &getfoilset($item);
	if( $globalfoilsettype == -1 )	{
		$out=$keepoptions[$masterfoilset]{$item};
		$out_html=$keepoptions_html[$masterfoilset]{$item};
	}
	else	{
		$out=$keepoptions[$globalfoilsettype]{$item};
		if($item eq 'bestfoilseturl')	{
			$out= &jumpfoil($locpath,$out);
		}
		$out_html=$keepoptions_html[$globalfoilsettype]{$item};
	}
	return unless $out;
	&recursewich($out,$out_html,$valuewww{$item});
	return unless($item eq 'signature');
	$saveline=$lineacc;
	$lineacc='';
	&recursewich('',1,$saveline);
#
}	# End makeitem for quantity in persoptions
#
sub makeglobalitem { # Output a simple global item held in $item
#
	my($item)=@_;
#
	&recursewich('',1,$valuewww{$item});
#
}	# End makeglobalitem 
#
#	Disentangle tags of form fileindicator/tag where
#	fileindicator is either
#	mixed : denotes filesystem for mixed script or current single foilset
#	local : denotes current foilset being processed
#	nickname : denotes foilset with this nickname
#	getfoilset used by makefile and makeitem ONLY
sub getfoilset	{
#
	my($tag)=@_;
	my($slash,$newtag,$key);
#
	$slash=index($tag,"/");
	return(-1,$tag)	if( $slash < 0 );
#
	$key= substr($tag,0,$slash);
	$key =~ s/\s+//g;
	$key =~ tr/A-Z/a-z/;
	return(-1,$tag) unless($key);
#
	$newtag=substr($tag,$slash+1);
	return(-1,$newtag) if( $key eq 'mixed' );
	return($currentfoilset,$newtag) if( $key eq 'local');
	return(-1,$tag) unless defined($nametofoilset{$key});
	return($nametofoilset{$key},$newtag);
#
}	# End getfoilset
#
sub sandwich	{	# Convert item for output
#
	my($out,$out_html,$format)=@_;
#
	$out = &tohtml($out) unless $out_html;
	if( $format )	{
		if( $format =~ m/(.*)({})(.*)/ )	{
			$out= $1.$out.$3;
		}
		else 	{
			$out = $format.$out;
		}
	}
	$lineacc .= $out;
#
}	# End Sandwich conversion
#
sub recursewich	{	# Recursive sandwich
#
	my($out,$out_html,$format)=@_;
	my($test);
#
	$out = &tohtml($out) unless $out_html;
	$end1=$format;
#
	while($end1)	{
		if( &curlyscan1($end1) )	{
			$lineacc .= $begin1;
			unless( $tag1 )	{
				$lineacc .= $out;
				next;
			}
			$test=$classwww{$tag1};
			die("Illegal recursive tag ",$tag1,"\n") if( $test==21 || $test==22 || ($test>=2 && $test<=6) );
			die("Illegal recursive tag ",$tag1,"\n") if( $test==10 || $test==12 );
			$lineacc .= $today if $test==31;
			&makeitem($tag1) if $test==1;
			&makefile($tag1) if $test==11;
			&makefoilnum if $test == 13;
			&makepadfoilnum if $test==14;
			}
		else	{
			$lineacc .= $begin1;
			last;
		}
	}
}	# End recursewich
sub numberwich	{	# Recursive sandwich for numerical arguments
#	$numberinc is numerical increment
#	$numbertype is type of number (0 nonpadded 1 padded)
#	$format is format processed recursively
#
	my($numberinc,$numbertype,$format)=@_;
	my($point,$test);
#
	$end1=$format;
#
	while($end1)	{
		if( &curlyscan1($end1) )	{
			$lineacc .= $begin1;
			unless( $tag1 )	{
				if($globalfoilsettype == -1)	{
					$point=$mixedfoilno+$numberinc;
					$point=$currentmaxfoilno if($point < 1);
					$point=1 if($point > $currentmaxfoilno);
				}
				else	{
					$point=$currentfoilno+$numberinc;
					$point=$totalfoilcount[$globalfoilsettype] if($point < 1);
					$point=1 if($point > $totalfoilcount[$globalfoilsettype]);
				}
				if( $numbertype == 0 )	{
					$out=$point;
				}
				else	{
					$out= &externalnumericlabel($point);
				}
				$lineacc .= $out;
				next;
			}
			$test=$classwww{$tag1};
			die("Illegal recursive tag ",$tag1,"\n") if( $test==21 || $test==22 || ($test>=2 && $test<=6) );
			die("Illegal recursive tag ",$tag1,"\n") if( $test==10 || $test==12 );
			$lineacc .= $today if $test==31;
			&makeitem($tag1) if $test==1;
			&makefile($tag1) if $test==11;
			&makefoilnum if $test == 13;
			&makepadfoilnum if $test==14;
			}
		else	{
			$lineacc .= $begin1;
			last;
		}
	}
}	# End numberwich
#
sub makeabstract	{ # Read abstract
#
	if( $scriptabstract ne 'masterabstract' )	{
		$mixedfoilno=$scriptabstract;
		$currentfoilset=$listoffoilsets[$mixedfoilno-1];
		$currentfoilno=$listoffoils[$mixedfoilno-1];
		&makefoil(1);
		return;
	}
#
	$bulletsongif=0;
	$bulletsongif=1 if $keepoptions[$currentfoilset]{"bulletsongif"} eq "on";
	$abstract=1;
	$linetypept=\@{$keepabslinetype[$currentfoilset]};
	$linehtmlpt=\@{$keepabslinehtml[$currentfoilset]};
	$lineitselfpt=\@{$keepabslineitself[$currentfoilset]};
	$missingoption=$keepabsmissingoption[$currentfoilset];
	$curline=$keeplinesperabstract[$currentfoilset];
	$setwwwref=0	unless (($currentfoilset != $masterfoilset) || $wwwabstractdone || ($loctype != 2));
#
#
}	# End makeabstract
sub makefoil	{ # Read in foils
#
	my($source)=@_;
#
	unless($source)	{	# Ordinary Foil access
		die("Illegal Position of readfoil\n") unless ($looptype ==2 || $looptype==1);
		$abstract=0;
	}
	else	{
		$abstract=1;
	}
	$setwwwref=$mixedfoilno	unless( $wwwfoilsdone[$mixedfoilno] || ($loctype != 2));
        $bulletsongif=0;
        $bulletsongif=1 if $keepoptions[$currentfoilset]{"bulletsongif"} eq "on";
	if($currentfoilno > 0)	{	# Foil not abstract
		$linetypept=\@{$keeplinetype[$currentfoilset][$currentfoilno]};
		$linehtmlpt=\@{$keeplinehtml[$currentfoilset][$currentfoilno]};
		$lineitselfpt=\@{$keeplineitself[$currentfoilset][$currentfoilno]};
		$missingoption=$keepmissingoption[$currentfoilset][$currentfoilno];
		$curline=$keeplinesperfoil[$currentfoilset][$currentfoilno];
	}
	else	{	# Abstract not foil (possible in script)
		$linetypept=\@{$keepabslinetype[$currentfoilset]};
		$linehtmlpt=\@{$keepabslinehtml[$currentfoilset]};
		$lineitselfpt=\@{$keepabslineitself[$currentfoilset]};
		$missingoption=$keepabsmissingoption[$currentfoilset];
		$curline=$keeplinesperabstract[$currentfoilset];
	}
#
}	# End makefoil
#
sub setimagesize	{ # If Necessary set Image Size
# Global Parameter $ImageSizeOption  Controls This!
#
	my($inputoption)=@_;
	my($imagefile,$imagedata,$imagewidth,$imagehgt);
#
	unless( $ImageSizeOption )	{
		return if( $inputoption==0 );
		$lineacc .= 'horiz';
		return;
	}
#
	unless( $abstract )	{	# Ordinary Foil
		$imagefile = $foilrawimage[$currentfoilset][$currentfoilno] unless $multi;
		$imagefile = $scriptrawimage[$mixedfoilno] if $multi;
	}
	else	{ # Abstract
		if( ($globalfoilsettype == -1) && $multi )	{ # Script abstract
			$imagefile = $scriptabsrawimage;
		}
		else	{
			$imagefile = $absrawimage[$currentfoilset];
		}
	}
	unless( -e $imagefile )	{
		die 'Error as bad Image File ',$imagefile,' from ',$currentfoilset,$currentfoilno,$mixedfoilno,"\n";
	}
	$imagedata = `/usr/local/archives/public/html/users/gcf/meryem/req/img/bin/identify $imagefile`;
	chomp($imagedata);
	$imagedata =~ m%(\d+)x(\d+)\D%;
	$imagewidth=$1;
	$imagehgt=$2;
	if( ($imagewidth <=0) || ($imagewidth > 10000))	{
		print "Implausible Image Width ",$imagewidth," for file ",$imagefile,"\n";
		return;
	}
	if( ($imagehgt <=0) || ($imagehgt > 10000))	{
		print "Implausible Image Height ",$imagehgt," for file ",$imagefile,"\n";
		return;
	}
	if( $inputoption == 0 )	{	# {imagesize}
		if( $imagewidth > $imagehgt )	{ # Natural Landscape Format
			$lineacc .= ' '.$imagestring_landscape; }
		else	{ # Portrait
			$lineacc .= ' '.$imagestring_portrait; }
	}
	else	{ # {imagetype}
		if( $imagewidth > $imagehgt )   { # Natural Landscape Format
			$lineacc .= 'horiz'; }
		else    { # Portrait
			$lineacc .= 'vert'; }
	}
	return;
}
#
sub makemissing	{	# Output missing string
#	Return 1 if skipped
#
	my($tag)=@_;
#
	die("Illegal Missing reference\n")	unless( $currentfoilno || $abstract==1);
	return 1 if($missingoption==4);
	$out="See also color IMAGE" if $missingoption==3;
	$out="Important Information in IMAGE" if $missingoption==2;
	$out="Critical Information in IMAGE"  if $missingoption==1;
	&recursewich($out,1,$valuewww{$tag});
	return 0;
#
}	# End Output of missing string
#
sub makeviewname	{
#
	my($view)=@_;
#
	if( $view eq 'image' )	{
		return "NOimage" if ($missingoption==4);
		return "OPTIONALimage" if ($missingoption==3);
		return "USEFULimage" if ($missingoption==2);
		return "CRITICALimage";
	}
	return "ONLYhtml" if ($missingoption==4);
	return "OKhtml" if ($missingoption==3);
	return "almostOKhtml" if ($missingoption==2);
	return "POORhtml";
#
}
#
sub maketitle	{	# Output foil Title
#
	my($out);
#
	$out="foil/title" if $abstract==0;
	$out="abstract/title" if $abstract==1;
	&sandwich($foiltitle[$currentfoilset][$currentfoilno],$foiltitle_html[$currentfoilset][$currentfoilno],$valuewww{$out}) if $abstract==0;
	if( $abstract == 1 )	{
		if($globalfoilsettype == -1 )	{
			&sandwich($abstracttitle[$masterfoilset],$abstracttitle_html[$masterfoilset],$valuewww{$out});
		}
		else	{
			&sandwich($abstracttitle[$currentfoilset],$abstracttitle_html[$currentfoilset],$valuewww{$out});
		}
	}
#
}	# End maketitle
#
sub makeprotectedtitle	{	# Output foil Title PROTECTED with back Quotes
#
	my($out);
#
	$out="foil/protectedtitle" if $abstract==0;
	$out="abstract/protectedtitle" if $abstract==1;
	&sandwich(&protectquote($foiltitle[$currentfoilset][$currentfoilno]),$foiltitle_html[$currentfoilset][$currentfoilno],$valuewww{$out}) if $abstract==0;
	if( $abstract == 1 )	{
		if($globalfoilsettype == -1 )	{
			&sandwich(&protectquote($abstracttitle[$masterfoilset]),$abstracttitle_html[$masterfoilset],$valuewww{$out});
		}
		else	{
			&sandwich(&protectquote($abstracttitle[$currentfoilset]),$abstracttitle_html[$currentfoilset],$valuewww{$out});
		}
	}
#
}	# End makeprotectedtitle
#
sub maketitlesize	{	# Output Size of foil Title
#
	$lineacc .= &setcharactersize($foiltitle[$currentfoilset][$currentfoilno],$foiltitle_html[$currentfoilset][$currentfoilno],'') if $abstract==0;
	if( $abstract == 1 )	{
		if($globalfoilsettype == -1 )	{
			$lineacc .= &setcharactersize($abstracttitle[$masterfoilset],$abstracttitle_html[$masterfoilset],'');
		}
		else	{
			$lineacc .= &setcharactersize($abstracttitle[$currentfoilset],$abstracttitle_html[$currentfoilset],'');
		}
	}
#
}	# End maketitlesize
#
sub makealiaslist	{ # Make list of aliases
#
	my($outputtype)=@_;
	my($name,$out,$save,$times,$i,$num);
#
	foreach $name  (sort keys(%wwwalias_url)) 	{
		next unless $times=$wwwalias_url_used{$name};
		&foilflush(CURFILE);
		$save=$linesize;
		$linesize=200;
		&foillineout('<br> key <b> '. $name.' </b> <a href="'. $wwwalias_url{$name} .'"> URL ' . $wwwalias_url{$name} . '</a>',1,CURFILE);
		$out='';
		$out .= ' * <b>' . $wwwalias_title{$name} . '</b>' if ((defined $wwwalias_titlegiven{$name}) && ($wwwalias_titlegiven{$name} ==1));
		$out .= ' (' . $wwwalias_comment{$name} .')' if $wwwalias_comment{$name};
		$out .= ' by ' . $wwwalias_author{$name} if $wwwalias_author{$name};
		$out .= ' on ' . $wwwalias_date{$name} if $wwwalias_date{$name};
		&foillineout($out,1,CURFILE) if $out;
		$linesize=$save;
		&foilflush(CURFILE);
		&foillineout(' <br> <tt> Times ' . $times . ' Foils referenced </tt>',1,CURFILE);
		for( $i=0;$i<$wwwurlref;$i++)	{
			next if $tagreferenced[$i] ne $name;
			$num=$foilreferenced[$i];
			if( $num > 0 )	{
			 	&foillineout(' <b> <a href="#local' . $num . '" > Foil ' . $num . ' </a> </b>',1,CURFILE);
			}
			elsif( $num < 0 ) 	{ # Script
			 	&foillineout(' <b> <a href="#localscriptline' . (-$num-1) .'" > Script </a> </b>',1,CURFILE);
			}
			else	{	# Abstract
			 	&foillineout(' <b> <a href="#localabstract" > Abstract </a> </b>',1,CURFILE);
			}
		}
		&foilflush(CURFILE);
	}
#
#	Full list of aliases including those not referenced
	return if $outputtype==7;
	&foillineout(' <br><hr> <h3>Full Alias list including those not referenced</h3>',1,CURFILE);
	&foilflush(CURFILE);
	foreach $name  (sort keys(%wwwalias_url)) 	{
		&foilflush(CURFILE);
		$save=$linesize;
		$linesize=200;
		&foillineout('<br> key <b> '. $name.' </b> <a href="'. $wwwalias_url{$name} .'"> URL ' . $wwwalias_url{$name} . '</a>',1,CURFILE);
		$out='';
		$out .= ' * <b>' . $wwwalias_title{$name} . '</b>' if ((defined $wwwalias_titlegiven{$name}) && ($wwwalias_titlegiven{$name} ==1));
		$out .= ' (' . $wwwalias_comment{$name} .')' if $wwwalias_comment{$name};
		$out .= ' by ' . $wwwalias_author{$name} if $wwwalias_author{$name};
		$out .= ' on ' . $wwwalias_date{$name} if $wwwalias_date{$name};
		&foillineout($out,1,CURFILE) if $out;
		$linesize=$save;
		&foilflush(CURFILE);
	}
#
}	# End alias list
#
sub makebullets	{	# Make Body of Foil
#
	my($entry,$i,$header,$label,$level,$bullet,$run);
#
	my($flag)=@_;
#
	die("Illegal bullets\n")	unless ($abstract >=0);
	$header="foil/"	if $abstract==0;
	$header="abstract/"	if $abstract==1;
	$bullet=0;
	&outacc;
#
	for($i=0;$i < $curline; $i++)	{
		$entry=$$linetypept[$i];
		if( $entry==2 )	{	# HTMLline
			&sandwich($$lineitselfpt[$i],1,$valuewww{$header."htmlline"});
			&outacc;
			next;
		}
		next if( ($bulletsongif==0) && ($nobulletsifgif==1) && ($missingoption != 4) && ($loctype != 10) && ($loctype != 11) );
		next if( ($bulletsongif==0) && ($nobulletsifgif==1) && (($loctype==10) || ($loctype==11)) && ($missingoption==1 || $missingoption==2)  );
		next if( ($bulletsongif==0) && ($flag == 1) );
		next unless ($entry >= 102);
		$label="bullet1" if $entry==102;
		$label="bullet2" if $entry==103;
		$label="bullet3" if $entry>=104;
		$label= $header.$label;
		$level=$entry-101;
		if($level > $bullet)	{
			for($run=0;$run<$level-$bullet;$run++)	{
				&foillineout("<ul>",1,CURFILE);
				&foilflush(CURFILE);
			}
		}
		if($level < $bullet)	{
			for($run=0;$run<$bullet-$level;$run++)	{
				&foillineout("</ul>",1,CURFILE);
				&foilflush(CURFILE);
			}
		}
		$lineacc="<li>";
		&sandwich($$lineitselfpt[$i],$$linehtmlpt[$i],$valuewww{$label});
		&outacc;
		$bullet=$level;
#
	}	# end loop over input lines
	for($run=0;$run<$bullet;$run++)	{
		&foillineout("</ul>",1,CURFILE);
		&foilflush(CURFILE);
	}
	$wwwabstractdone=1	if($setwwwref==0);
	$wwwfoilsdone[$setwwwref]=1	if($setwwwref>0);
	$setwwwref= -100001;
}	# End makebullets
#
sub makebullet1size	{	# Output size of primary bullets (bullet1,htmlline)
#
	my($entry,$i,$bulletsize);
#
	my($flag)=@_;
#
	die("Illegal bullets\n")	unless ($abstract >=0);
	$bulletsize='';
#
	for($i=0;$i < $curline; $i++)	{
		$entry=$$linetypept[$i];
		if( $entry==2 )	{	# HTMLline
			$bulletsize = &setcharactersize($$lineitselfpt[$i],1,$bulletsize);
			next;
		}
		next if( ($bulletsongif==0) && ($nobulletsifgif==1) && ($missingoption != 4) && ($loctype != 10) && ($loctype != 11) );
		next if( ($bulletsongif==0) && ($nobulletsifgif==1) && (($loctype==10) || ($loctype==11)) && ($missingoption==1 || $missingoption==2)  );
		next if( ($bulletsongif==0) && ($flag == 1) );
		next unless ($entry == 102);
		$bulletsize = &setcharactersize($$lineitselfpt[$i],$$linehtmlpt[$i],$bulletsize);
#
	}	# end loop over input lines
#
	$lineacc .= $bulletsize;
#
}	# End makebullet1size
#
sub makebullet2size	{	# Output size of secondary bullets (bullet2 and above)
#
	my($entry,$i,$bulletsize);
#
	my($flag)=@_;
#
	die("Illegal bullets\n")	unless ($abstract >=0);
	$bulletsize='';
#
	for($i=0;$i < $curline; $i++)	{
		$entry=$$linetypept[$i];
		next if( $entry==2 );	# HTMLline
		next if( ($bulletsongif==0) && ($nobulletsifgif==1) && ($missingoption != 4) && ($loctype != 10) && ($loctype != 11) );
		next if( ($bulletsongif==0) && ($nobulletsifgif==1) && (($loctype==10) || ($loctype==11)) && ($missingoption==1 || $missingoption==2)  );
		next if( ($bulletsongif==0) && ($flag == 1) );
		next unless ($entry > 102);
		$bulletsize = &setcharactersize($$lineitselfpt[$i],$$linehtmlpt[$i],$bulletsize);
#
	}	# end loop over input lines
#
	$lineacc .= $bulletsize;
#
}	# End makebullet2size
#
sub makeref { # Output a button reference augmented by $num -- the second argument
# Assume $currentfoilno holds current file count on separate files 
#
	my($lookup,$num)=@_;
	my($format);
#
	return unless( $format=$valuewww{$lookup});
	&numberwich($num,1,$format);
#
}	# End makeref button
#
sub makelocalref { # Output a button reference augmented by $num -- the second argument
# Assume $currentfoilno holds current file count on separate files 
#
	my($lookup,$num)=@_;
	my($format);
#
	return unless( $format=$valuewww{$lookup});
	&numberwich($num,0,$format);
#
}	# End makelocalref button
#
sub makefoilnum	{
# Foil number assumed held in $currentfoilno
#	
	my($out);
	$out=$currentfoilno;
	$out=$mixedfoilno	if( $globalfoilsettype == -1);
	$out='abstract' unless( $out>0 );
	&sandwich($out,1,$valuewww{"localfoil#"});
#
}	# End makefoilnum
#
sub makepadfoilnum	{
# Foil number assumed held in $currentfoilno
#	
	my($out,$format);
	$out=$currentfoilno;
	$out=$mixedfoilno	if( $globalfoilsettype == -1);
	$out=&externalnumericlabel($out);
	$format=$valuewww{"extfoil#"};
	&sandwich($out,1,$format);
#
}	# End makepadfoilnum
#
sub searchline	{	# Construct Search Line
#
	my($foilnum,$linename)=@_;
	my($color,$begfoil,$endfoil,$i,$iuse,$writefile,$begfile,$endfile);
#
	$writefile = $locpath;
	$writefile =~ m%(^.*/)([^/]*)$%;
	$begfile=$1;
	$endfile=$2;
	$endfile .= '#search';
#
	&outacc;
	$nextfoil= $foilnum+1;
	$nextfoil=1 if( $nextfoil > $currentmaxfoilno);
	$lineacc = '<a';
	$lineacc .= ' name="' . $linename . '"'	if $linename;
	$lineacc .= ' href="'. (&externalnumericlabel($nextfoil)).$endfile. '">Next </a>';
#
	$endfoil= &tenround($foilnum+25);
	$endfoil=$currentmaxfoilno if( $endfoil > $currentmaxfoilno );
	$begfoil= $endfoil-30;
	if( $begfoil <=1)	{
		$begfoil=1;
	}
	else	{
		$begfoil= &tenround($begfoil+5);
	}
#
#	Initial multiple of ten
	$color=$displayparms{"col1"};
	if($begfoil > 1 )	{
		for($i=0; $i < $begfoil; $i +=10)	{
			$iuse=$i;
			$iuse=1	if $iuse==0;
			&searchline_help($iuse,$color,$endfile);
		}
	}
	for($i=$begfoil; $i <= $endfoil; $i++ )	{
		$color=$displayparms{"col1"};
		$color=$displayparms{"col2"} if(($i == ($foilnum+1)) || ($i == ($foilnum-1)) );
		$color=$displayparms{"col3"} if( $i == $foilnum);
		&searchline_help($i,$color,$endfile);
	}
	$color=$displayparms{"col1"};
	for($i=$endfoil+10; $i <= $currentmaxfoilno; $i +=10)       {
		&searchline_help($i,$color,$endfile);
	}
#
}	# End Searchline
#
sub searchline_help  {       # Help Construct Search Line
#
	my($number,$color,$filename_end)=@_;
	my($numberout);
#
	return if($number <1);
	return if($number >$currentmaxfoilno);
#
	if( &tenround($number) == $number )	{
		$numberout= ' '. $number . '/';
	}
	else	{
		$numberout= $number - &tenround($number);
	}
	$lineacc .= '<a href="'. (&externalnumericlabel($number)) . $filename_end . '" ' . $color . '>' . $numberout . '</a>';
	return;
#
}       # End Searchline_help
#
sub tenround	{	# Round to lower multiple of ten
#
	my($numin)=@_;
#
	$numin =~ s%(\.)(.*)%%;
	$numin =~ s%.$%%;
	if($numin)	{
		return (10*$numin);
	}
	else	{
		return 0;
	}
#
}	#	End tenround
#
sub makefile	{	# Construct file pointer
#
	my($item)=@_;
	my($indirect,$relpath,$newitem,$wwwdir_to,$wwwserver_to);
#
	($globalfoilsettype,$newitem)= &getfoilset($item);
	die("Undefined file ",$item, "\n")	unless $to=$filepath{$newitem};
#
	$relpath=$locpath;
#
	if( $globalfoilsettype > -1 )	{
		$wwwdir_to=$foilsetparms[$globalfoilsettype]{"wwwdir"};
		$wwwserver_to=$foilsetparms[$globalfoilsettype]{"wwwserver"};
		if( defined($wwwserver) && defined($wwwserver_to) && ($wwwserver_to ne $wwwserver))	{
			$lineacc .= $wwwserver_to . '/' . $wwwdir_to . '/' . $to;
			return;
		}
		if( $wwwdir_to ne $wwwdir )	{
			$to= $wwwdir_to .'/' . $to;
			$relpath= $wwwdir . '/' . $relpath;
		}
	}
	$indirect= &jumpfoil($relpath,$to);
	$lineacc .= $indirect;
#
}	# End makefile
sub jumpfoil{ # Return relative path from $from to $to
#
	my($from,$to)=@_;
	my($path);
#
	print('Error in jumpfoil: ',$from,' * ',$loctemplate,' ',$looping,' ** ',$currentfoilno,"\n") unless defined($to);
	return $to if( $to =~ m%^/% );
	return $to if( $to =~ m%^http% );
	die("Undefined jump from ",$from," to",$to,"\n")	if( $from =~ m%^/% );
#
	$from =~ s%/\./%/%g;
	$from =~ s%//%/%g;
	$from =~ s%^\./%%;	# Remove null directory movements
	$to =~ s%/\./%/%g;
	$to =~ s%//%/%g;
	$to =~ s%^\./%%;	# Remove null directory movements
	return $to unless $from =~ s%/[^/]*$%%;	# Remove last slash and filename leaving directories
	$path='';
	$from =~ s%\.%\\\.%g;	# Ensure all dots are real dots in $from!
	while($from)	{
		if( ($to =~ m%^${from}/%) )	{
			$to =~ s%^${from}/%% ;
			last;
		}
		if( ($to =~ m%^${from}$%) )	{
			$to =~ s%^${from}%%;
			last;
		}
		$path .= '../';
		$from='' unless $from =~ s%/[^/]+$%% ;
	}
	$path .= $to;
	return $path;
}	# End routine returning relative path
#
# Break up argument into $begin{$tag}$end finding first such pair
sub curlyscan	{ 
#
	my($inline)=@_;
	my($line);
#
	$line=$inline;
	$begin='';
	while($line)	{
#
		if( $line =~ m%([^{]*){([^}]*)}(.*)% 	)	{
			if( $1 =~ m%\\$% )	{
				$begin .= $1 . '{';
				$line = $2.'}'.$3;
				next;
			}
			$begin .= $1;
			$end=$3;
			$tag=$2;
			$tag =~ s/\s*//g;
			$tag =~ tr/A-Z/a-z/;
			if($tag =~ m%([^=]*)=(.*)%)	{
				$tag=$1;$tagvalue=$2;
			}
			else	{
				$tagvalue=0;
			}
			die("Illegal tag ",$tag," in ",$inline,"\n") unless $classwww{$tag};
			return 1;
		}
		$begin=$inline;
		$end='';
		$tag='';
		return 0;
	}	# End loop over starting {
	$begin=$inline;
	return 0;
#
}	# End curly scan
#
# Break up argument into $begin1{$tag1}$end1 finding first such pair
sub curlyscan1	{ 
#
	my($inline)=@_;
	my($line);
#
	$line=$inline;
	$begin1='';
	while($line)	{
#
		if( $line =~ m%([^{]*){([^}]*)}(.*)%s 	)	{
			if( $1 =~ m%\\$% )	{
				$begin1 .= $1 . "{";
				$line = $2.'}'.$3;
				next;
			}
			$begin1 .= $1;
			$end1=$3;
			$tag1=$2;
			$tag1 =~ s/\s*//g;
			$tag1 =~ tr/A-Z/a-z/;
			if($tag1 =~ m%([^=]*)=(.*)%)     {
				$tag1=$1;$tag1value=$2;
			}
			else    {
				$tag1value=0;
			}
			if( $tag1 )	{	# $tag1 can be null
				die("Illegal tag ",$tag1," in ",$inline,"\n") unless $classwww{$tag1};
			}
			return 1;
		}
		$begin1=$inline;
		$end1='';
		$tag1='';
		return 0;
	}	# End loop over starting {
	$begin1=$inline;
	return 0;
#
}	# End curly scan1
#
sub externalnumericlabel	{ # return  header of foil label for HTML or gif foil
#
	my($num)=@_;
	return 'abstract' unless($num>0);
	sprintf("%03d",$num);
}	# End routine to set HTML or IMAGE foil label
#
#	Protect quotes in String
sub protectquote	{ # return backslashed string
#
	my($dangerous)=@_;
	$dangerous =~ s/([^\\])'/$1\\'/g;
	$dangerous =~ s/([^\\])"/$1\\"/g;
	return $dangerous
#
}	# End protectquote
#
sub setcharactersize	{ # return additional character string info
#
	my($charstring,$html,$currentsummary)=@_;
	my($left,$begin,$num,$newpos);
#
	if($html == 1 )	{	# This has HTML tags
		$charstring =~ s%<[^>]*>%%g;
	}	# End removing tag data
	$begin=0;
	$left=length($charstring);
	while( ($newpos = index($charstring,"\n",$begin)) > -1 )	{ # Newlines embedded
		$num=$newpos-$begin;
		$currentsummary .= ',' ;
		$currentsummary .= $num;
		$left -= ($num+1);
		$begin=$newpos+1;
	}
	if($left)	{ # No newlines/remainder
		$currentsummary .= ',' ;
		$currentsummary .= $left;
	}
	return $currentsummary;
#
}	# End setcharactersize
#
#	Join  2 lines together returning result
#       add white space as necessary
sub join	{
	my($a,$b) = @_;
	$a = $a . ' '	if( ($a =~ /\S$/) && ($b =~ /^\S/) ) ;
	return $a . $b ;
}
#	Compare if two strings equal if lowercased and deblanked
sub lcequal	{
	my($a,$b)=@_;
	$a =~ s/\s*//g;
	$a =~ tr/A-Z/a-z/;
	$b =~ s/\s*//g;
	$b =~ tr/A-Z/a-z/;
	$a eq $b;
}	# End comparison of two strings
#
sub tohtml	{ # Convert HTML magic characters in current line
	my($convline)=@_;

	return($convline)	unless $convline;
	$convline =~ s/&/&amp;/g;
	$convline =~ s/</&lt;/g;
	$convline =~ s/>/&gt;/g;
	$convline =~ s/"/&quot;/g;
	$convline;
}
#
#	Optional Conversion based on $usehtml;
sub maybehtml	{
	my($convline,$usehtml)=@_;
	
	$convline = &tohtml($convline)	unless $usehtml;
	$convline;
}
#
#	Clean up list of blank and comma separated numbers
sub clean	{
	my($line)=@_;
	$line =~ s/ /,/g;
	$line = ',' . $line;
	$line = $line . ',';
	$line =~ s/,+/,/g;
	$line =~ s/,(0+)/,/g;
	$line;
}
#
#	Output a line with elegant continuation if possible
#	$linesize is size of line and 
#	$linect counts used positions (initialize to zero)
#	$outcontd=1 implies we use Contd: to denote continuation
#	$nocol=1 implies we strip XXXX: option from line
#	Arguments are $line to output, $usehtml and Handle of output file
#	$usehtml controls HTML conversion (=0 implies scan for html special
#		characters to convert to &  ; format)
# 	$newlinetobr controls treatment of embedded newlines
# 	$newlinetobr=0 gives newline on output while
# 	$newlinetobr=1 outputs <br> with NO newline
#	$prettyprint defaults to 0 -- if nonzero
#	Output continuation lines starting with $prettyout taking $prettyskip
#	characters
#
sub foillineout	{
	my($newline,$usehtml,$outhandle)=@_;
	my($linesave,$used,$out,$colon,$want,$left,$crlf,$neat,$putout,$garbage);
#
	$linesave=$linesize;
	if($prettyprint)	{
		$garbage = $newline;
		$garbage =~ s%<[^>]*>%%g;
		$prettyextra= length($newline)-length($garbage);
		$linesize += $prettyextra if $prettyprint;
	}
#
        if( $prettyprint != $oldprettyprint)    {
       		 if($prettyprint ==1)    {
                        &foilflush($outhandle);
			print $outhandle "<pre>\n";
                 }
                 else   {
                        &foilflush($outhandle);
			print $outhandle "</pre>\n";
                 }
        }
	$oldprettyprint=$prettyprint;
#
	$newline = &tohtml($newline)	unless $usehtml;
#
	if( $nocol)	{
		$colon=index($newline,':');
		$newline=substr($newline,$colon+1);
	}
#
	$left=length($newline);
	$used=0;
	LEFTWHILE:	while($left)	{
		$want=$linesize-$linect;
		if( $want <= 0 )	{
			if( $outcontd )	{
				print $outhandle "\nContd:";
				$linect=6;
			}
			else	{
				print $outhandle "\n";
				$linect=0;
				if($prettyprint)	{
					$linect = $prettyskip;
					$linesize=$linesave;
					print $outhandle $prettyout;
				}
			}
			$want=$linesize-$linect;
			$used=0;
		}
#
#	Cope with newlines in output string
		while( ($crlf=index($newline,"\n")) != -1 && ($crlf <= $want) )	{
			if( $nonewlines==0 ) 	{
				if( $newlinetobr==1 && $prettyprint==0)	{
					$out=substr($newline,0,$crlf);
					print $outhandle $out,"<br>";
				}
				else	{
					$out=substr($newline,0,$crlf+1);
					print $outhandle $out;
				}
			}
			else	{
				$out=substr($newline,0,$crlf);
				print $outhandle $out," ";
			}
			$left -= $crlf+1;
			last LEFTWHILE if( $left <= 0 )	;
			$newline=substr($newline,$crlf+1);
			if( $outcontd )	{
				print $outhandle "CONTD:";
				$linect=6;
			}
			else	{
				$linect=0;
				if($prettyprint)	{
					$linect = $prettyskip;
					$linesize=$linesave;
					print $outhandle $prettyout;
				}
			}
			$want=$linesize-$linect;
			$used=0;
		}
#
#	Case when buffer bigger than output string
		if( $left <= $want )	{
			print $outhandle $newline, ;
			$linect += $left;
			last;
		}
#
		$out=substr($newline,0,$want+1);
		if( $out =~ /([\s\n]+)([^\s\n]*)$/ )	{
			$neat=length($2);
			$neat=1 if $neat==0;
			$putout=$want+1-$neat;
		}
		else	{	$putout=0;	}
#
		if($putout == 0 )	{  # Output Anyway if no good heuristic!
			if($used==0)	{
				print $outhandle $newline,"\n";
				$linect=0;
				if($prettyprint)	{
					$linect = $prettyskip;
					$linesize=$linesave;
					print $outhandle $prettyout;
				}
				last;
			}
			if( $outcontd )	{
				print $outhandle "\nContd:";
				$linect=6;
			}
			else	{
				print $outhandle "\n";
				$linect=0;
				if($prettyprint)	{
					$linect = $prettyskip;
					$linesize=$linesave;
					print $outhandle $prettyout;
				}
			}
			$used=0;
			redo;
		}
#
		$out=substr($newline,0,$putout);
		print $outhandle $out;
		$newline=substr($newline,$putout);
		$left -= $putout;
		$used=1;
		if( $left )	{
			if( $outcontd )	{
				print $outhandle "\nContd:";
				$linect=6;
			}
			else	{
				print $outhandle "\n";
				$linect=0;
				if($prettyprint)	{
					$linect = $prettyskip;
					$linesize=$linesave;
					print $outhandle $prettyout;
				}
			}
			$used=0;
		}

	}	# End loop over character strings in $newline
	$linesize=$linesave;
#
}	# end foillineout
#
sub outdata	{
	my($line,$htmloption,$outhandle)=@_;
#
	if( $htmloption != $currenthtmloption )	{
		$currenthtmloption=$htmloption;
		if($htmloption)	{
			print $outhandle "Html:\n";
		}
		else	{
			print $outhandle "Endhtml:\n";
		}
	}
	$outcontd=1;
	$linect=0;
	$nocol=0;
	&foillineout($line,1,$outhandle);
	foilflush($outhandle);
#
}	# End outdata for a logical line of colon data
#
sub foilflush	{
	my($outfoilflush)=@_;
#
	return	if( $linect==0 );
	print $outfoilflush "\n";
	$linect=0;
}
#
#
1
