Index: main/trunk/greenstone2/bin/script/gti.pl
===================================================================
--- main/trunk/greenstone2/bin/script/gti.pl	(revision 30718)
+++ main/trunk/greenstone2/bin/script/gti.pl	(revision 30719)
@@ -679,11 +679,9 @@
     foreach my $chunk_key (keys(%source_file_key_to_submission_mapping)) {
 
-	# Kathy introduced escaped colons ("\:") into chunk keys in properties files (greenstone3/metadata_names),
-	# but they're not escaped in the submitted XML versions. So have to carefully compare for submissions:
-	my $escaped_chunk_key = $chunk_key;
-	$escaped_chunk_key =~ s/:/\\:/g;
+	# Kathy introduced escaped colons ("\:") into chunk keys in properties files (greenstone3/metadata_names),	
+	# but they're not escaped in the submitted XML versions, nor are they escaped in memory (in the $chunk_key)
 
 		# Make sure the submitted chunk still exists in the source file
-		if (!defined($source_file_key_to_text_mapping{$escaped_chunk_key})) {
+		if (!defined($source_file_key_to_text_mapping{$chunk_key})) {
 			&log_message("Warning: Source chunk $chunk_key no longer exists (ignoring submission).");
 			delete $source_file_key_to_submission_mapping{$chunk_key};
@@ -693,12 +691,12 @@
 		
 		# Make sure the submitted source chunk matches the source file chunk
-		if ($source_file_key_to_submission_mapping{$chunk_key} ne &unmake_text_xml_safe($source_file_key_to_text_mapping{$escaped_chunk_key})) {
+		if ($source_file_key_to_submission_mapping{$chunk_key} ne &unmake_text_xml_safe($source_file_key_to_text_mapping{$chunk_key})) {
 		#if (&unmake_text_xml_safe($source_file_key_to_submission_mapping{$chunk_key}) ne &unmake_text_xml_safe($source_file_key_to_text_mapping{$chunk_key})) {
 		    		#print STDERR "**** $source_file_key_to_submission_mapping{$chunk_key}\n";
 				#print STDERR "**** " . &unmake_text_xml_safe($source_file_key_to_text_mapping{$chunk_key}) ."\n";
 
-			&log_message("Warning: Source chunk $escaped_chunk_key has changed (ignoring submission).");
+			&log_message("Warning: Source chunk $chunk_key has changed (ignoring submission).");
 			&log_message("Submission source: |$source_file_key_to_submission_mapping{$chunk_key}|");
-			&log_message("      Source text: |$source_file_key_to_text_mapping{$escaped_chunk_key}|");
+			&log_message("      Source text: |$source_file_key_to_text_mapping{$chunk_key}|");
 			delete $source_file_key_to_submission_mapping{$chunk_key};
 			delete $target_file_key_to_submission_mapping{$chunk_key};
@@ -710,9 +708,7 @@
     foreach my $chunk_key (keys(%target_file_key_to_submission_mapping)) {
 		# Only apply the submission if it is a change, unless -force_submission has been specified
-	my $escaped_chunk_key = $chunk_key;
-	$escaped_chunk_key =~ s/:/\\:/g;
-		if ($force_submission_flag || !defined($target_file_key_to_text_mapping{$escaped_chunk_key}) || $target_file_key_to_submission_mapping{$chunk_key} ne $target_file_key_to_text_mapping{$escaped_chunk_key}) {
-			$target_file_key_to_text_mapping{$escaped_chunk_key} = $target_file_key_to_submission_mapping{$chunk_key};
-			$target_file_key_to_gti_comment_mapping{$escaped_chunk_key} = "Updated $submission_date by $submitter_username";
+		if ($force_submission_flag || !defined($target_file_key_to_text_mapping{$chunk_key}) || $target_file_key_to_submission_mapping{$chunk_key} ne $target_file_key_to_text_mapping{$chunk_key}) {
+			$target_file_key_to_text_mapping{$chunk_key} = $target_file_key_to_submission_mapping{$chunk_key};
+			$target_file_key_to_gti_comment_mapping{$chunk_key} = "Updated $submission_date by $submitter_username";
 		}
     }
@@ -1621,14 +1617,19 @@
 		$line =~ s/(\s*)$//;  # Remove any nasty whitespace, carriage returns etc.
 		
-		$line =~ s/\\:/ESCAPEDCOLONTEMP/g; # an escaped colon "\:" should only occur in the chunk_key portion of the line
-
-		# Line contains a dictionary string
-		if ($line =~ /^(\S+?)[:|=](.*)$/) {
+		# a property line has a colon/equals sign as separator that is NOT escaped with a backslash (both keys and values
+		# can use the colon or = sign. But in the key, such a char is always escaped. Unfortunately, they've not always been
+		# escaped in the values. So we get the left most occurrence by not doing a greedy match (use ? to not be greedy).
+		# So find the first :/= char not preceded by \. That will be the true separator of a chunk_key and its value chunk_text
+
+		if ($line =~ m/^(\S*?[^\\])[:|=](.*)$/) { #if ($line =~ /^(\S+?)[:|=](.*)$/) {
+		    # Line contains a dictionary string
+
+		    # Unused but useful: http://stackoverflow.com/questions/87380/how-can-i-find-the-location-of-a-regex-match-in-perl
+		    # http://perldoc.perl.org/perlvar.html
+		    
 		    $chunk_key = $1;
-
-		    # an escaped colon "\:" should only occur in the chunk_key portion of the line, put it back in, escaped as before
-		    if($chunk_key =~ m/ESCAPEDCOLONTEMP/) {
-			$chunk_key =~ s/ESCAPEDCOLONTEMP/\\:/g;
-		    }
+		    # remove the escaping of any :/= property separator from the chunk_key in memory, 
+		    # to make comparison with its unescaped version during submissions easier. Will write out with escaping.
+		    $chunk_key =~ s/\\([:=])/$1/g;		 
 		    
 		    $startindex = $i;
@@ -1654,13 +1655,9 @@
     my ($chunk_text) = @_;
 	
-    $chunk_text =~ s/\\:/ESCAPEDCOLONTEMP/g; # an escaped colon "\:" should only occur in the chunk_key portion of the line.
-    # But it seems to occur in chunk text too now (before http:\\) in dictionary.properties.
-
-    # Simple: just remove string key    
-    $chunk_text =~ s/^(\S+?)[:|=](\s*)//s;
-
-    if($chunk_text =~ m/ESCAPEDCOLONTEMP/) { # put back the escaped colons
-	$chunk_text =~ s/ESCAPEDCOLONTEMP/\\:/g;
-    }
+    # Simple: just remove string key. 
+    # But key can contain an escaped separator (\: or \=).
+    # So just as in the previous subroutine, find the first (leftmost) : or = char not preceded by \. 
+    # That will be the true separator of a chunk_key and its value chunk_text
+    $chunk_text =~ s/^(\S*?[^\\])[:|=](\s*)//s; # $chunk_text =~ s/^(\S+)[:|=](\s*)//s;
 
     $chunk_text =~ s/(\s*)$//s;  # Remove any nasty whitespace, carriage returns etc.
@@ -1678,7 +1675,7 @@
     if ($chunk_text =~ /\#\s+(Updated\s+\d?\d-\D\D\D-\d\d\d\d.*)\s*$/i) {
 		return $1;
-}
-
-return undef;
+    }
+
+    return undef;
 }
 
@@ -1731,11 +1728,16 @@
 		my $target_file_chunk_text = $target_file_key_to_text_mapping->{$chunk_key} || "";
 		
+		# make sure any : or = sign in the chunk key is escaped again (with \) when written out 
+		# since the key-value separator in a property resource bundle file is : or =
+		my $escaped_chunk_key = $chunk_key;
+		$escaped_chunk_key =~ s/(:|=)/\\$1/g; #$escaped_chunk_key =~ s/([^\\])(:|=)/\\$1$2/g;
+		
 		# If no translation exists for this chunk, show this, and move on
 		if ($source_file_chunk_text ne "" && $target_file_chunk_text eq "") {
-			print TARGET_FILE "# -- Missing translation: $chunk_key\n";
+			print TARGET_FILE "# -- Missing translation: $escaped_chunk_key\n";
 			next;
 		}
-		
-		print TARGET_FILE "$chunk_key:$target_file_chunk_text";
+
+		print TARGET_FILE "$escaped_chunk_key:$target_file_chunk_text";
 		if ($target_file_key_to_gti_comment_mapping->{$chunk_key}) {
 			print TARGET_FILE "  # " . $target_file_key_to_gti_comment_mapping->{$chunk_key};
@@ -2202,11 +2204,16 @@
 			my $target_file_chunk_text = $target_file_key_to_text_mapping->{$global_chunk_key} || "";
 			
+			# make sure any : or = sign in the chunk key is escaped again (with \) when written out
+			# since the key-value separator in a property resource bundle file is : or =
+			my $escaped_chunk_key = $chunk_key;
+			$escaped_chunk_key =~ s/(:|=)/\\$1/g; #$escaped_chunk_key =~ s/([^\\])(:|=)/\\$1$2/g;
+
 			# If no translation exists for this chunk, show this, and move on
 			if ($source_file_chunk_text ne "" && $target_file_chunk_text eq "") {
-				print TARGET_FILE "# -- Missing translation: $chunk_key\n";
+				print TARGET_FILE "# -- Missing translation: $escaped_chunk_key\n";
 				next;
 			}
 			
-			print TARGET_FILE "$chunk_key:$target_file_chunk_text";
+			print TARGET_FILE "$escaped_chunk_key:$target_file_chunk_text";
 			if ($target_file_key_to_gti_comment_mapping->{$global_chunk_key}) {
 				print TARGET_FILE "  # " . $target_file_key_to_gti_comment_mapping->{$global_chunk_key};
