#!perl

# Copyright (c) 1997-1999 Symbian Ltd.  All rights reserved.

# Input: .cs-ptml
# Outputs: .sgml, .mbm-index

# Version Info:
# Version 006: Fixes bug where paragraph icons where not being recognised if the reference in the alc file
#              did not end with a space.
# Version 005: processes the customisation file .alc into an .alg file where references to graphics
#              for tip, note and important text are replace with correct graphic index in the mbm-list file
#              Also fixes a bug preventing the loading of graphic in from a multiple mbm file generated an
#              incorrect mbm-list ?(indexes off by one)
#              Also fixed a bug that causes graphics referenced more thatn one to be loaded into the
#              mbm-list more than once.
# Version 004: now ensures that no formatting is written to the application hint field
# Version 003: now allows order file to be unspecified in the project file
# Version 002: fixed a bug which only included topics in the first file of the source file list
# Version 001: processes and collates ptmls into sgml for the aleppo converter -
#					- forms heading 2's into topics
#					- provides conversion of Synonyms style into synonyms tags
#					- removes all paragrahs in 'Comment' style
#					- produces mbm list for later in the aleppo conversion process

# ------------------------------------- Global variables -----------------------------------
$current_line = "";		# current line (string)
$next_line = "";		# next line (string)
$eof = 0;				# has the end of file been reached (integer)
$line_number = 0;		# current line number (for error logging) (integer)
$within_topic = 0;		# boolean - whether or not the current line is within a topic (heading 2)
%order_list = ();		# internal representation of the order list
$graphic_index = 0;		# the current graphic index (increments for each successive graphic)
@source_filelist = ();	# list of the source files to process
%seen_graphic = ();	# array of the seen graphic files
# -------- filenames --------
$without_extender = "";	# input file without extender
$mbm_list_name = "";	# filename of mbm-list file
$output_name = "";		# filename of pipeline output file
$input_name = "";		# filename of input file
$order_name = "";		# filename of order file
# -------- arguments --------
$input_directory = pwd()."\\";			# default input directory is current directory 
$output_directory = pwd()."\\";			# default output directory is current directory
$auxiliary_directory = pwd()."\\";		# default auxiliary directory is current directory
$log_name = pwd()."\\aleppo.log";		# default logfile name
# ------------------------------------------------------------------------------------------

# --------------------------------- Start of Main() ----------------------------------------

&handle_command_line_args();										# calculate filenames

open(MBMFILE,">$mbm_list_name") || &log_die("Cannot create $mbm_list_name");	# open output file (.mbm-list)

&proc_customization();

&load_order_file();

open(OUTFILE,">$output_name") || &log_die("Cannot create $output_name");		# open output file (.sgml)
open(LOGFILE,">>$log_name") || &log_die("Cannot create $log_name");				# open error log for appending

$index = 0;
while ($current_filename = $source_filelist[$index]) {
	&log_error("Adding topics in ".$current_filename." to output file");
	&process_file($working_directory.$current_filename.".cs-ptml");
	$index++;
}

close(MBMFILE);
close(OUTFILE);
close(LOGFILE);

# ------------------------------------------------- End of Main() --------------------------------------------

sub process_file {
	my($input_name) = @_;
	my($graphic_ref);
	
	open(INFILE,"$input_name") || &log_die("Cannot find $input_name");			# open input file

	$eof = 0;
	# get first two lines
	if ($_ = <INFILE>) {								# get first line 
		$current_line = $_;								
		if ($_ = <INFILE>) {							# get next line
			$next_line = $_;
		} else {
			$eof = 2;									# end of file will be encountered after the next line
		}
		$_ = $current_line;								# set $_ to first line in file
	} else {
		$eof = 1;										# end of file encountered
	}

	$suppress_echoing_next_line = 0;
	$appname = "";

	while ($eof != 1)	{								# Iterate over all lines of the ptml file (with look ahead)
		$line_number++;									# increment line count (for error logging)		

		s/<ptml>//;										# convert <ptml> tag to nothing
		if (/<\/ptml>/) {								# convert </ptml> tag to nothing
			s/<\/ptml>//;
			if ($within_topic==1) {						# end the current topic before emitting the </sgml>
				print OUTFILE "</topic>\n";
			}
		}

		s/<p style="synonyms">(.*)<\/p>/<synonyms>$1<\/synonyms>/;	# convert synonyms style to synonyms tags
		s/<p style="comment">(.*)<\/p>\n//;							# delete comment paragraphs

		while (/<cs style="graphic link">(.*?)<\/cs>/) {		# repeatedly, translate 'graphic link' character style
			$graphic_ref=&translate_graphic_link($1);
			#substitute the graphic index
			if($graphic_ref ne "")
				{

				# replace the graphic link in the SGML with an indexed graphic entry
				s/<cs style="graphic link">$1<\/cs>/<graphic index=$graphic_ref>/;

				} else {
				&log_error("ERROR - Graphic $raw_link cannot be found.");
				# replace the graphic link with nothing
				s/<cs style="graphic link">$1<\/cs>//;
				}

		}

		if (/<h1>(.*)<\/h1>/) {
			$appname = $_;
			$appname =~ s/(\s*)&tab;(\s*)/ &mdash; /g;		# convert tabs in headings to mdash's (with trim white space)
			$appname =~ s/&tab;/&mdash;/g;
			$appname =~ s/<h1>(.*)<\/h1>\n/$1/;				# get the heading text
			$appname = &strip_all_styles($appname);			# strip style from the application name
		} elsif (/<h2>(.*)<\/h2>/) {					# if the line is a heading2 (a topic)
			if ($appname eq "") {
				&log_error("ERROR - There is no Heading 1 in the file before the current Heading 2");
			} else {
				$heading = $_;
				$heading =~ s/(\s*)&tab;(\s*)/ &mdash; /g;			# convert tabs in headings to mdash's (with trim white space)
				$heading =~ s/&tab;/&mdash;/g;
				$heading =~ s/<h(.)>(.*)<\/h\1>\n/$2/;				# get the heading text
				$anchor_name = &extract_anchor_name($heading,$next_line,$without_extender);
				&print_in_named_ptml($heading_level,$anchor_name,$heading);
			}
		} elsif ($next_line =~ /<p style="Hypertext Anchor">(.*)<\/p>\n/i) {	# if the line is a hypertext anchor...
			if ($current_line =~ /<h(.)>(.*)<\/h\1>/i) {				# check that its previous line is a heading
			} else {
				$anchor = $next_line;
				$anchor =~ s/<p style="Hypertext Anchor">(.*)<\/p>\n/$1/i;	
				&log_error("ERROR - Anchor without previous heading found: '$anchor'.");	# flag a warning if it isn't
				print OUTFILE;													# print this line
				$suppress_echoing_next_line = 1;									# and suppress echoing the illegal anchor
			}
		} else {
			if ($suppress_echoing_next_line == 0) {
				print OUTFILE;							# line isn't a heading or an anchor - output the line as it is
			} else {
				$suppress_echoing_next_line = 0;
			}
		}

		&get_next_line();
	}

	close(INFILE);
}

sub load_order_file {
	if ($order_name eq "") {} else {
		open(ORDERFILE,"$order_name") || &log_die("Cannot find $order_name");	# open order file
		$count = 1;
		while ($_ = <ORDERFILE>) {
			$anchor = $_;
			$anchor =~ s/(.*)\n/$1/;
			$anchor = lc($anchor);
			$order_list{$anchor} = $count;
			$count++;
		}
		close(ORDERFILE);
	}
}

sub get_next_line {
	# get next line (with look ahead)
	if ($eof < 2) {									# if $eof < 2 then end of file not encountered yet
		$current_line = $next_line;					# current line = next line
		if ($_ = <INFILE>) {
			$next_line = $_;						# next line = next line in file
		} else {
			$eof = 2;								# if eof then exit loop after processing current line
		}
		$_ = $current_line;
	} else {										
		$eof = 1;									# if $eof = 2 then end of file is after current line 
	}
}

sub print_in_named_ptml {
	my($heading_level,$anchor_name,$heading) = @_;	# assign arguments to clearer variable names
	
	if ($within_topic==1) {
		print OUTFILE "</topic>\n";
	}
	print OUTFILE "<topic application=\"$appname\"";
	if ($order_name ne "") {
		if ($anchor_name eq "") {} else {
			# lookup anchor in order-file
			$anchor_name = lc($anchor_name);			# convert into lower case as search should not be case-sensitive
			$order_number = $order_list{$anchor_name};
			if ($order_number > 0) {
				print OUTFILE " order=$order_number";
			} else {
				&log_error("ERROR - Cannot find '$anchor_name' in the order file. It will be ordered alphabetically.");
			}
		}
	}
	print OUTFILE ">\n";
	print OUTFILE "<topictitle>$heading</topictitle>\n";

	$within_topic = 1;
}

sub extract_anchor_name {
	my($heading,$next_line,$file_name) = @_;		# assign arguments to clearer variable names

	$anchor = "";
	if ($next_line =~ /<p style="Hypertext Anchor">(.*)<\/p>\n/i) {
		$anchor = $next_line;
		$anchor =~ s/<p style="Hypertext Anchor">(.*)<\/p>\n/$1/i;
		$anchor = &strip_all_styles($anchor);
		&get_next_line();							# skip over the anchor line in input file
	}
	return $anchor;
}

sub strip_all_styles {
	my($input_string) = @_;
	$input_string =~ s/<cs([^>]*)>(.*?)<\/cs>/$2/g;		# strip character styles

	while ($input_string =~ /<([^>]*)>(.*?)<\/\1>/) {
		$input_string =~ s/<([^>]*)>(.*?)<\/\1>/$2/;		# strip simple styles: italic, bold, etc.
	}
	return $input_string;
}

sub handle_command_line_args {
	&extract_command_line_args("altopic");
	$output_no_extender = $output_filename;
	$output_no_extender =~ s/(.*)\.(.*)/$1/;
	$output_name = $working_directory.$output_no_extender.".sgml";
	$mbm_list_name = $working_directory.$output_no_extender.".mbm-list";
}

# ---------------------------------------- Graphics linking -------------------------------------------

sub translate_graphic_link
	{
	my($raw_link) = @_;
	my($graphic_ref);

	#remove any "
	$raw_link=~s/\"//g;
	
	$raw_link =~ /archive=([^ ]*) name=([^ ]*)/i;

	$graphic_ref=$seen_graphic{$raw_link};

	if($graphic_ref eq "")
		{
	
		$graphic_archive = $1;
		$graphic_name = $2;
		$search_graphic_name = "EMbm".$graphic_archive.$graphic_name;

		# attempt to find the archive, and the name in the archive
		$graphic_directory_index = 0;
		$file_found = 0;
		while (($cur_graphic_directory = $graphic_directory_list[$graphic_directory_index]) && $file_found==0)
			{
			$mbg_filename = $cur_graphic_directory.$graphic_archive.".mbg";
			if (open(MBGFILE,$mbg_filename))
				{
				$name_found = 0;
				while (($mbg_line = <MBGFILE>) && $name_found==0)
					{
					if ($mbg_line =~ /enum/)
						{
						$bitmap_index = -1;			# names about to start
						$mbg_line = <MBGFILE>;		# skip the next line (it's just a { character)
						}
					else
						{
						$bitmap_index++;
						if ($mbg_line =~ /$search_graphic_name/i)
							{
							$bitmap_filename = $cur_graphic_directory.$graphic_archive.".mbm";
							$name_found = 1;
							$file_found = 1;
							}
						}
					}
				close(MBGFILE);
				}
			else
				{
				$mbm_filename = $cur_graphic_directory.$graphic_archive."\\$graphic_name.mbm";
				if (open(MBGFILE,$mbm_filename))
					{
					$bitmap_filename = $mbm_filename;
					$bitmap_index = 0;
					$name_found = 1;
					$file_found = 1;
					close(MBGFILE);
					}
				}
			$graphic_directory_index++;
			}

		if ($file_found==1)
			{
			# write the graphic to the mbm-aux file
			$absolute_filename = &get_abs_filename($bitmap_filename);
			print MBMFILE "<graphic index=$graphic_index archive=$graphic_archive name=$graphic_name bitmapfile=$absolute_filename bitmapindex=$bitmap_index>\n";

			# put the graphic index into the seen graphic array
			$seen_graphic{$raw_link}=$graphic_index;

			$graphic_ref=$graphic_index;
	
			$graphic_index++;
			}
		}
	$graphic_ref;
	}

sub get_abs_filename {
	my($rel_filename) = @_;

	if ($rel_filename =~ /:/) {
		$abs_filename = $rel_filename;
	} else {
		$cur_dir = &pwd();
		if (substr($rel_filename,0,1) eq "\\") {
			$cur_dir =~ s/(.*):(.*)/$1:/;
			$abs_filename = $cur_dir.$rel_filename;
		} else {
			$abs_filename = $cur_dir.$rel_filename;
		}
	}
	return $abs_filename;
}

# ----------------------------------------- Misc functions --------------------------------------------

sub extract_command_line_args {
	my($program_title) = @_;

	if ($this_arg = pop(@ARGV)) {
		$project_filename = $this_arg;			# project_filename is the last argument
		&get_project_file();
	} else {
		print "Use of $program_title:\n\t$program_title project-file\n";
		exit;
	}
}

sub get_project_file {
	open(PROJFILE,"$project_filename") || &log_die("Cannot find $project_filename");	# open project file

	while ($_ = <PROJFILE>)	{							# Iterate over all lines of the project file
		s/\n//;												# remove the end of line character from the line
		s/(.*)#(.*)/$1/;									# remove any comment from the line
		if (/sourcefile/) {
			s/sourcefile (.*)/$1/;
			$source_files = $_;
			@source_filelist = split(/ /,$source_files);
		} elsif (/outputfile/) {
			s/outputfile (.*)/$1/;
			$output_filename = $_;
		} elsif (/graphicsdirectory/) {
			s/graphicsdirectory (.*)/$1/;
			@graphic_directory_list = split(/ /);
		} elsif (/workingdirectory/) {
			s/workingdirectory (.*)/$1/;
			$working_directory = $_;
		} elsif (/inputdirectory/) {
			s/inputdirectory (.*)/$1/;
			$input_directory = $_;
		} elsif (/orderfile/) {
			s/orderfile (.*)/$1/;
			$order_filename = $_;
		} elsif (/customizationfile/) {
			s/customizationfile (.*)/$1/;
			$cust_filename = $_;
			}
		}
	
	close(PROJFILE);

	$input_name = $working_directory.$without_extender.$input_extension;
	$output_name = $working_directory.$without_extender.$output_extension;
	$mbm_list_name = $working_directory.$without_extender."mbm-list";
	if ($order_filename ne "") {
		$order_name = $input_directory.$order_filename;
	} else {
		$order_name = "";
		&log_error("WARNING - No orderfile specified. Ordering topics alphabetically");
	}
}

sub write_attribute {
	my($file_handle, $tag, $value) = @_;			# assign arguments to clearer variable names
	$value =~ s/"/""/;								# replace single quotes in value string with double quotes
	print $file_handle "$tag=\"$value\"";
}

sub log_error {
	my($error_string) = @_;

	open(LOGFILE,">>$log_name") || die "Cannot create $log_name";				# open error log for appending
	print LOGFILE "$error_string\n";
	close(LOGFILE);
	print "$error_string\n";
}

sub log_die {
	$error_string = $_[0];
	print LOGFILE "ERROR - $error_string\n";
	die "ERROR - $error_string";
}

sub proc_customization
	{
	my($output_name);
	my($graphic_ref);

	if($cust_filename)
		{
		$output_name=$cust_filename;

		#strip off the path
		$output_name=~s/.*\\//;
		#add the working directory
		$output_name=$working_directory.$output_name;
	
		$output_name=~/(.*)\./;
		$output_name=$1.".alg";

		#open the input and output file
		open(INPUT,"$cust_filename") || &log_die("Cannot open $cust_filename");			# open the input file
		open(OUTFILE,">$output_name") || &log_die("Cannot create $output_name");		# open output file (.sgml)
		open(LOGFILE,">>$log_name") || &log_die("Cannot create $log_name");				# open error log for appending

		#loop through the lines in the customisation file
		while(<INPUT>)
			{

			#check if this line is significant
			if (/tipeffects/ or /noteeffects/ or /importanteffects/)
				{
				#see if the line has a archive and name within it
				if(/(archive=.* name=[^ >]*)/)
					{
				
					# translate this graphic link
					$graphic_ref=translate_graphic_link($1);

					if($graphic_ref ne "")
						{
						s/archive=.* name=[^ >]*(.*)/graphic_index=$graphic_ref$1/;
						}
					else
						{
						&log_error("ERROR - Graphic $1 cannot be found.");
						}
					}
				}
			print OUTFILE "$_";
			}
		close(INPUT);
		close(OUTFILE);
		close(LOGFILE);
		}
	}



# ---------------------------------------- Directory handling fns -----------------------------------

sub pwd {
	$dir = `cd`;								# find current directory
	chop($dir);									# remove the eoln
	return $dir;								# and return it
}





__END__
