Index: /gsdl/trunk/etc/marc2qdc.txt
===================================================================
--- /gsdl/trunk/etc/marc2qdc.txt	(revision 15018)
+++ /gsdl/trunk/etc/marc2qdc.txt	(revision 15018)
@@ -0,0 +1,90 @@
+
+
+# The following mapping is based on the Library of Congress crosswalk given at:
+#   http://www.loc.gov/marc/marc2dc.html
+
+245			  -> Title				
+130, 210, 240, 242, 246	  -> Title^Alternative	
+730, 740		  -> Title^Alternative	
+
+100, 110, 111		  -> Creator			
+700, 710, 711		  -> Creator			
+720			  -> Creator
+
+# at later date might want to distinguish between
+# (LCSH encoding, 2nd indicator=0) and (MeSH encoding, 2nd indicator=2)
+600, 610, 611, 630, 650	  -> Subject		        # LCSH or MeSH encoding	
+050			  -> Subject		        # LCC encoding
+082			  -> Subject			# DDC encoding
+080			  -> Subject			# UDC encoding
+
+500-504, 507-519, 521-529 -> Description
+531-539, 541-545, 547-599 -> Description
+505			  -> Description^TableofContents
+520			  -> Description^Abstract	# First indicator=3
+
+260$a$b			  -> Publisher			
+
+260$c$g			  -> Date^Created		
+533$d			  -> Date^Created
+260$c			  -> Date^Issued
+# Control field substring, not currently supported by mapping
+# 008/07-10		  -> Date^Issued   
+
+# Leader fields not currently supported by mapping
+# Leader06, Leader07	  -> Type			# DCMI Type Vocabulary
+655			  -> Type			# Subfield $2=dct
+
+856$q			  -> Format			# IMT encoding
+300$a			  -> Format^Extent
+533$e			  -> Format^Extent
+340$a			  -> Format^Medium
+
+856$u			  -> Identifier			# URI encoding
+
+786$o			  -> Source			# URI encoding
+
+# Control field substring, not currently supported
+# 008/35-37		  -> Language			# ISO 639-2 encoding 
+041			  -> Language			# ISO 639-2 encoding 
+546			  -> Language			# RFC1766 encoding
+
+775			  -> Relation^IsVersionOf	
+786$n$t			  -> Relation^IsVersionOf	
+775,786$o		  -> Relation^IsVersionOf	# URI encoding
+775$n$t			  -> Relation^HasVersion	
+775$o			  -> Relation^HasVersion	# URL encoding
+785$n$t			  -> Relation^IsReplacedBy	
+785$o			  -> Relation^IsReplacedBy	# URL encoding
+780$n$t			  -> Relation^Replaces	
+780$o			  -> Relation^Replaces		# URL encoding
+538			  -> Relation^Requires	
+760	  		  -> Relation^IsPartOf	
+773$n$t			  -> Relation^IsPartOf	
+440,490,800,810,811,830	  -> Relation^IsPartOf
+760,773$o		  -> Relation^IsPartOf		# URL encoding
+774$n$t			  -> Relation^HasPart		
+774$o			  -> Relation^HasPart		# URL encoding
+510			  -> Relation^IsReferencedBy	
+776$n$t			  -> Relation^IsFormatOf	
+530			  -> Relation^IsFormatOf	
+776$o			  -> Relation^IsFormatOf	# URL encoding
+530$u			  -> Relation^IsFormatOf	# URL encoding
+776$n$t			  -> Relation^HasFormat	
+530			  -> Relation^HasFormat		
+776$o			  -> Relation^HasFormat		# URL encoding
+530$u			  -> Relation^HasFormat		# URL encoding
+
+522, 651		  -> Coverage^Spatial		
+255			  -> Coverage^Spatial		# Some 255 information equivalent to DC encoding scheme but different syntax
+ 			
+650$z			  -> Coverage^Spatial
+752			  -> Coverage^Spatial
+
+043$c,044$c		  -> Coverage^Spatial		# ISO 3166 encoding
+651			  -> Coverage^Spatial		# Subfield $2=tgn # Encoding TGN
+513$b			  -> Coverage^Temporal	
+033$a			  -> Coverage^Temporal	
+
+506, 540		  -> Rights			
+
Index: /gsdl/trunk/perllib/plugins/BasPlug.pm
===================================================================
--- /gsdl/trunk/perllib/plugins/BasPlug.pm	(revision 15017)
+++ /gsdl/trunk/perllib/plugins/BasPlug.pm	(revision 15018)
@@ -109,4 +109,9 @@
 	'type' => "string",
 	'reqd' => "no" },
+      { 'name' => "use_as_doc_identifier",
+	'desc' => "{BasPlug.use_as_doc_identifier}",
+	'type' => "string",
+	'reqd' => "no" ,
+	'deft' => "" } ,
       { 'name' => "input_encoding",
 	'desc' => "{BasPlug.input_encoding}",
@@ -867,4 +872,32 @@
 }
 
+
+sub add_OID
+{
+    my $self = shift (@_);  
+    my ($doc_obj) = @_;
+
+    # See if a metadata field is specified as the field
+    if ((defined $self->{'use_as_doc_identifier'}) && ($self->{'use_as_doc_identifier'} ne "")) {
+	my $metadata_doc_id = $self->{'use_as_doc_identifier'};
+
+	# Consider "tidying" up metadata_doc_id to be something
+	# suitable in a URL
+	# Could even support a user specified plugin RE for this.
+
+	my $top_section = $doc_obj->get_top_section();
+	my $oid = $doc_obj->get_metadata_element($top_section,$metadata_doc_id);
+##	print STDERR "**** oid = $oid\n";
+    	$doc_obj->set_OID($oid);
+    }
+    # See if there is a plugin-specific set_OID function...
+    elsif (defined ($self->can('set_OID'))) {
+	# it will need $doc_obj to set the Identifier metadata...
+	$self->set_OID(@_); # pass through any extra arguments supplied
+    } else {
+	# use the default set_OID() in doc.pm
+	$doc_obj->set_OID();
+    }
+}
 
 # The BasPlug read_into_doc_obj() function. This function does all the
@@ -957,14 +990,6 @@
     # do any automatic metadata extraction
     $self->auto_extract_metadata ($doc_obj);
-   
-    # add an OID
-    # see if there is a plugin-specific set_OID function...
-    if (defined ($self->can('set_OID'))) {
-	# it will need $doc_obj to set the Identifier metadata...
-	$self->set_OID($doc_obj);
-    } else {
-	# use the default set_OID() in doc.pm
-	$doc_obj->set_OID();
-    }
+
+    $self->add_OID($doc_obj);
     
     return (1,$doc_obj);
Index: /gsdl/trunk/perllib/plugins/MARCPlug.pm
===================================================================
--- /gsdl/trunk/perllib/plugins/MARCPlug.pm	(revision 15017)
+++ /gsdl/trunk/perllib/plugins/MARCPlug.pm	(revision 15018)
@@ -45,4 +45,10 @@
 	'type' => "string",
 	'deft' => "marctodc.txt",
+	'hiddengli' = "yes", # deprecated in favour or 'metadata_mapping_file'
+	'reqd' => "no" },
+      { 'name' => "metadata_mapping_file",
+	'desc' => "{MARCXMLPlug.metadata_mapping_file}",
+	'type' => "string",
+	'deft' => "",
 	'reqd' => "no" },
       { 'name' => "process_exp",
@@ -80,4 +86,19 @@
     my $self = new SplitPlug($pluginlist, $inputargs, $hashArgOptLists);
 
+    # 'metadata_mapping' was used in two ways in the plugin: as a plugin
+    # option (filename) and as a datastructure to represent the mapping.
+    # In MARXXMLPlug (written later) the two are separated: filename is
+    # represented through 'metadata_mapping_file' and the data-structure
+    # mapping left as 'metadata_mapping'
+    # 'metadata_mapping' still present (but hidden in GLI) for
+    # backwards compatibility, but 'metadata_mapping_file' is used by
+    # preference
+
+    if ($self->{'metadata_mapping_file'} eq "") {
+	# If nothing set in the new version, use the old version
+	# that defaults to 'marctodc.txt'
+	$self->{'metadata_mapping_file'} = $self->{'metadata_mapping'};
+    }
+
     $self->{'type'} = "";
     
@@ -92,12 +113,12 @@
 
     # read in the metadata mapping file
-    my $mm_file =
-	&util::filename_cat( $ENV{'GSDLHOME'}, "etc", $self->{'metadata_mapping'} );
-
-    if (!-e $mm_file)
+
+    my $mm_file = &util::locate_config_file($self->{'metadata_mapping_file'}); 
+
+    if (!defined $mm_file)
     {
 
 	my $msg = "MARCPlug ERROR: Can't locate mapping file \"" .
-	    $self->{'metadata_mapping'} . "\".\n    This file should be at $mm_file\n" .
+	    $self->{'metadata_mapping_file'} . "\".\n" .
 		"    No marc files can be processed.\n";
 
@@ -131,4 +152,6 @@
 	}
 	close(MMIN);
+
+	$self->{'metadata_mapping'} = \@metadata_mapping;
     }
     else
@@ -137,5 +160,5 @@
     }
 
-    $self->{'metadata_mapping'} = \@metadata_mapping;
+
 
     $self->SUPER::init(@_);
Index: /gsdl/trunk/perllib/plugins/MARCXMLPlug.pm
===================================================================
--- /gsdl/trunk/perllib/plugins/MARCXMLPlug.pm	(revision 15017)
+++ /gsdl/trunk/perllib/plugins/MARCXMLPlug.pm	(revision 15018)
@@ -42,4 +42,5 @@
 		  'desc' => "{MARCXMLPlug.metadata_mapping_file}",
 		  'type' => "string",
+		  'deft' => "marctodc.txt",
 		  'reqd' => "no" }];
 
@@ -62,4 +63,5 @@
     
     $self->{'content'} = "";
+    $self->{'xmlcontent'} = "";
     $self->{'record_count'} = 1;
     $self->{'language'} = "";
@@ -83,4 +85,125 @@
 
 
+sub _parse_marc_metadata_mapping
+{
+    my $self = shift(@_);
+    my ($mm_file,$metadata_mapping) = @_;
+
+    my $outhandle = $self->{'outhandle'};
+
+    if (open(MMIN, "<$mm_file"))
+    {
+	my $l=0;
+	my $line;
+	while (defined($line=<MMIN>))
+	{
+	    $l++;
+	    chomp $line;
+	    $line =~ s/#.*$//; # strip out any comments, including end of line
+	    next if ($line =~ m/^\s*$/); 
+	    $line =~ s/\s+$//; # remove any white space at end of line
+
+	    my $parse_error_count = 0;
+	    if ($line =~ m/^-(\d+)\s*$/) {
+		# special "remove" rule syntax
+		my $marc_info = $1;
+		if (defined $metadata_mapping->{$marc_info}) {
+		    delete $metadata_mapping->{$marc_info};
+		}
+		else {
+		    print $outhandle "Parse Warning: Did not file pre-existing rule $marc_info to remove";
+		    print $outhandle " on line $l of $mm_file:\n";
+		    print $outhandle "  $line\n";
+		}
+	    }
+	    elsif ($line =~ m/^(.*?)->\s*([\w\^]+)$/)
+	    {
+		my $lhs = $1;
+		my $gsdl_info = $2;
+
+		my @fields = split(/,\s*/,$lhs);
+		my $f;
+		while ($f  = shift (@fields)) {
+		    $f =~ s/\s+$//; # remove any white space at end of line
+
+		    if ($f =~ m/^(\d+)\-(\d+)$/) {
+			# number range => genrate number in range and
+			# push on to array
+			push(@fields,$1..$2);
+			next;
+		    }
+
+		    if ($f =~ m/^(\d+)((?:(?:\$|\^)\w)*)\s*$/) {
+
+			my $marc_info = $1;
+			my $opt_sub_fields = $2;
+
+			if ($opt_sub_fields ne "") {			
+			    my @sub_fields = split(/\$|\^/,$opt_sub_fields);
+			    shift @sub_fields; # skip first entry, which is blank
+
+			    foreach my $sub_field (@sub_fields) {
+				$metadata_mapping->{$marc_info."\$".$sub_field} = $gsdl_info;
+			    }
+			}
+			else {
+			    # no subfields to worry about
+			    $marc_info =~ s/\^/\$/;
+			    $metadata_mapping->{$marc_info} = $gsdl_info;
+			}
+		    }
+		    else {
+			$parse_error_count++;
+		    }
+		}
+	    }
+	    else
+	    {
+		$parse_error_count++;
+	    }
+
+	    if ($parse_error_count>0) {
+		
+		print $outhandle "Parse Error: $parse_error_count syntax error(s) on line $l of $mm_file:\n";
+		print $outhandle "  $line\n";
+	    }
+	}
+	close(MMIN);
+    }
+    else
+    {
+	print STDERR "Unable to open $mm_file: $!\n";
+    }
+}
+
+
+sub parse_marc_metadata_mapping
+{
+    my $self = shift(@_);
+    my ($mm_file_or_files) = @_;
+
+    my $metadata_mapping = {};
+
+    if (ref ($mm_file_or_files) eq 'SCALAR') {
+	my $mm_file = $mm_file_or_files;
+	$self->_parse_marc_metadata_mapping($mm_file,$metadata_mapping);
+    }
+    else {
+	my $mm_files = $mm_file_or_files;
+	
+	# Need to process files in reverse order.  This is so in the
+	# case where we have both a "collect" and "main" version,
+	# the "collect" one tops up the main one
+
+	my $mm_file;
+	while ($mm_file = pop(@$mm_files)) {
+	    $self->_parse_marc_metadata_mapping($mm_file,$metadata_mapping);
+	}
+    }
+
+    return $metadata_mapping;
+}
+
+
 sub init {
     my $self = shift (@_);
@@ -93,18 +216,12 @@
     }
 
-    my $metadata_mapping = {};
-
     # read in the metadata mapping file
-    my $mm_file = $self->{'metadata_mapping_file'}; 
-
-    if (! defined $mm_file or $mm_file eq ""){
-      	$mm_file = &util::filename_cat( $ENV{'GSDLHOME'}, "etc","marctodc.txt" );
-	$self->{'metadata_mapping_file'} = $mm_file;
-    }
-
-    if (!-e $mm_file)
+    my $mm_files = &util::locate_config_files($self->{'metadata_mapping_file'}); 
+
+
+    if (scalar(@$mm_files)==0)
     {
 	my $msg = "MARCXMLPlug ERROR: Can't locate mapping file \"" .
-	    $self->{'metadata_mapping'} . "\".\n    This file should be at $mm_file\n" .
+	    $self->{'metadata_mapping_file'} . "\".\n " .
 		"    No marc files can be processed.\n";
 
@@ -115,33 +232,8 @@
 	# If we exit here, then pluginfo.pl will exit too!
     }
-    elsif (open(MMIN, "<$mm_file"))
-    {
-	my $l=1;
-	my $line;
-	while (defined($line=<MMIN>))
-	{
-	    chomp $line;
-	    if ($line =~ m/^(\d+\w?)\s*->\s*([\w\^]+)$/)
-	    {
-		my $marc_info = $1;
-		my $gsdl_info = $2;
-		$metadata_mapping->{$marc_info} = $gsdl_info;
-	    }
-	    elsif ($line !~ m/^\#/       # allow comments (# in first column)
-		   && $line !~ m/^\s*$/) # allow blank lines
-	    {
-		print $outhandle "Parse error on line $l of $mm_file:\n";
-		print $outhandle "  \"$line\"\n";
-	    }
-	    $l++
-	}
-	close(MMIN);
-    }
-    else
-    {
-	print STDERR "Unable to open $mm_file: $!\n";
-    }
-
-    $self->{'metadata_mapping'} = $metadata_mapping;
+    else {
+	$self->{'metadata_mapping'} = $self->parse_marc_metadata_mapping($mm_files);
+    }
+
 
     ##map { print STDERR $_."=>".$metadata_mapping->{$_}."\n"; } keys %$metadata_mapping;
@@ -191,5 +283,6 @@
     my $element = shift;  
 
-    my $text =  $self->escape_text($_); 
+    my $text = $_;
+    my $escaped_text =  $self->escape_text($_); 
   
     $self->{'current_element'} = $element;
@@ -203,5 +296,5 @@
     }
 
-  
+
     my $processor = $self->{'processor'};
   
@@ -225,7 +318,4 @@
 	$doc_obj->add_metadata($doc_obj->get_top_section(), "FileFormat", "XML");
 
-	$doc_obj->set_OID();
-	$self->set_OID($doc_obj, $doc_obj->get_OID() , $self->{'record_count'});
-
 	my $outhandle = $self->{'outhandle'};
 	print $outhandle "Record $self->{'record_count'} - MARCXMLPlug: processing $self->{'file'}\n" if $self->{'verbosity'} > 1;
@@ -254,4 +344,6 @@
    if ($element eq "record"){
         $self->{'indent'} = 0;
+        $self->{'content'} = "";
+        $self->{'xmlcontent'} = "";
     }
     else {
@@ -264,8 +356,17 @@
     }
     
-    
-   if ($element ne "collection"){
-        $self->{'content'} .= "<br/>".$self->calculate_indent($self->{'indent'}).$text;
+
+    if ($element eq "collection") {
+	# remember the full start tag for <collection ...>
+	# This is needed to wrap around each <record> when generating its associate MARCXML file
+
+        $self->{'xmlcollectiontag'} = $text;
+    }
+    else {
+        $self->{'content'} .= "<br/>" if ($element ne "record");
+        $self->{'content'} .= $self->calculate_indent($self->{'indent'}).$escaped_text;
+        $self->{'xmlcontent'} .= $text;
    }
+    
 }
 
@@ -275,5 +376,7 @@
     my $self = shift(@_);
     my ($expat, $element) = @_;
-    my $text =  $self->escape_text($_); 
+
+    my $text = $_;
+    my $escaped_text =  $self->escape_text($_); 
  
     if ($element eq "record" and defined $self->{'doc_obj'}) {
@@ -281,6 +384,36 @@
 	my $processor = $self->{'processor'};
 	my $doc_obj = $self->{'doc_obj'};
-        $self->{'content'} .= "<br/>".$text;
+        $self->{'content'} .= "<br/>".$escaped_text;
+        $self->{'xmlcontent'} .= $text;
       
+
+	my $top_section = $doc_obj->get_top_section();
+
+	my $tmp_marcxml_filename = &util::get_tmp_filename().".xml";
+	if (open (XMLOUT,">$tmp_marcxml_filename")) {
+
+	    print XMLOUT "<?xml-stylesheet type=\"text/xsl\" href=\"MARC21slim2English.xsl\"?>\n";	    
+	    my $xml_content = $self->{'xmlcontent'};
+
+	    $xml_content = $self->{'xmlcollectiontag'}.$xml_content."</collection>";
+
+	    print XMLOUT $xml_content;
+
+	    close(XMLOUT);
+
+	    $doc_obj->associate_file($tmp_marcxml_filename,"marcxml.xml","text/xml", $top_section);
+	    
+	    # assicate xsl style file for presentation as HTML
+	    my $xsl_filename = &util::filename_cat($ENV{'GSDLHOME'},"etc","MARC21slim2English.xsl");
+	    $doc_obj->associate_file($xsl_filename,"MARC21slim2English.xsl","text/xml", $top_section);
+
+	}
+	else {
+	    my $outhandle = $self->{'outhandle'};
+	    print $outhandle "Warning: Unable for write out associated MARCXML file $tmp_marcxml_filename\n";
+	}
+
+	$self->add_OID($doc_obj,  $self->{'record_count'});
+
 	$doc_obj->add_utf8_text($doc_obj->get_top_section(),$self->{'content'});
         $processor->process($doc_obj);
@@ -288,4 +421,5 @@
         ##clean up
 	$self->{'content'} = "";  
+	$self->{'xmlcontent'} = "";  
 	$self->{'doc_obj'} = undef;
         return;
@@ -298,30 +432,44 @@
 	my $doc_obj = $self->{'doc_obj'};
 
-       ##map { print STDERR $_."=>".$marc_mapping->{$_}."\n"; } keys %$marc_mapping;
-       ##map { print STDERR $_."=>".$metadata_mapping->{$_}."\n"; } keys %$metadata_mapping;
+##	print STDERR "**** Marc Record\n";
+##      map { print STDERR $_."=>".$marc_mapping->{$_}."\n"; } keys %$marc_mapping;
+##	print STDERR "**** Metadata Mapping\n";
+##      map { print STDERR $_."=>".$metadata_mapping->{$_}."\n"; } keys %$metadata_mapping;
+
 
 	foreach my $marc_field (keys %$metadata_mapping){
-	    my ($meta_name,$meta_value);
+
+	    ## test whether this field has subfield
+	    my $subfield = undef;
+	    if ($marc_field =~ /(\d\d\d)(?:\$|\^)?(\w)/){
+		$marc_field = $1;
+		$subfield = $2;
+	    }
+
 	    my $matched_field = $marc_mapping->{$marc_field}; 
-	    my $subfield = undef;
-	    if (defined $matched_field){
-		## test whether this field has subfield
-		if ($marc_field =~ /\d\d\d(\w)/){
-		    $subfield = $1;
+
+	    if (defined $matched_field) {
+
+		my $meta_name  = undef;
+		my $meta_value = undef;
+
+		if (defined $subfield){
+		    $meta_name = $metadata_mapping->{$marc_field."\$".$subfield};
+
+		    $meta_value = $matched_field->{$subfield};
+		    
+		    if (!defined $meta_value) {
+			# record read in does not have the specified subfield
+			next;
+		    }
 		}
-		$meta_name = $metadata_mapping->{$marc_field};
-
-		if (defined $subfield){
-		    my %mapped_subfield = {@$matched_field};
-		    $meta_value = $mapped_subfield{$subfield};
-		}
-		else{ ## get all values 
-		    my $i =0;
-		    foreach my $value (@$matched_field){
-			if ($i%2 != 0){
-			    $meta_value .= $value." ";
-			}
-			$i++;
+		else {
+		    $meta_name = $metadata_mapping->{$marc_field};
+		    
+		    # no subfield => get all the values
+		    foreach my $value (sort keys %{$matched_field}) {
+			$meta_value .= $matched_field->{$value} ." ";
 		    }
+
 		}
 		
@@ -343,8 +491,10 @@
    if ($element eq "datafield"){
        $self->{'indent'} = 1;
-       $self->{'content'} .= "<br/>".$self->calculate_indent($self->{'indent'}).$text;
+       $self->{'content'} .= "<br/>".$self->calculate_indent($self->{'indent'}).$escaped_text;
+       $self->{'xmlcontent'} .= $text;
    }
     else{
-	$self->{'content'} .= $text;   
+	$self->{'content'} .= $escaped_text;   
+	$self->{'xmlcontent'} .= $text;   
     }
      
@@ -354,6 +504,11 @@
 sub set_OID {
     my $self = shift (@_);
-    my ($doc_obj, $id, $record_number) = @_;
-    
+    my ($doc_obj, $record_number) = @_;
+    
+    # first set it to generate hash value
+    $doc_obj->set_OID(); 
+
+    # then top it up with an "r" + record-number suffix
+    my $id = $doc_obj->get_OID();
     $doc_obj->set_OID($id . "r" . $record_number);
 }
@@ -363,14 +518,24 @@
     my ($expat) = @_;
 
+    my $text = $_;
+    my $escaped_text = $self->escape_text($_);
+
+    # protect against & in raw text file
+    $text =~ s/&/&amp;/g; # can't have & in raw form, even in 'raw' xml text
 
     ## store the text of a marc code, for exapmle 520a=>A poem about....
     if ($self->{'current_element'} eq "subfield" and $self->{'current_code'} ne "" and $_ ne "" ){
 	##stored it in the marc_mapping 
-     	push(@{$self->{'marc_mapping'}->{$self->{'current_tag'}}},$self->{'current_code'});
-	push(@{$self->{'marc_mapping'}->{$self->{'current_tag'}}},$_);
+
+	my $current_tag  = $self->{'current_tag'};
+	my $current_code = $self->{'current_code'};
+
+     	$self->{'marc_mapping'}->{$current_tag}->{$current_code} .= $_;
+
 	$self->{'current_code'} = "";
     }
     
-    $self->{'content'} .=$self->escape_text($_);
+    $self->{'content'} .= $escaped_text;
+    $self->{'xmlcontent'} .= $text;
    
 }
@@ -401,4 +566,17 @@
 
 
+sub unescape_text {
+    my ($self,$text) = @_;
+    # special characters in the xml encoding
+    $text =~ s/&lt;/</g;
+    $text =~ s/&gt;/>/g;
+    $text =~ s/&quot;/\"/g;
+
+    $text =~ s/&/&amp;/g; # can't have & in raw form, even in unescaped xml!
+
+    return $text;
+}
+
+
 1;
 
Index: /gsdl/trunk/perllib/plugins/PagedImgPlug.pm
===================================================================
--- /gsdl/trunk/perllib/plugins/PagedImgPlug.pm	(revision 15017)
+++ /gsdl/trunk/perllib/plugins/PagedImgPlug.pm	(revision 15018)
@@ -71,5 +71,5 @@
 #<PagedDocument>
 #<Metadata name="Title">The Title of the entire document</Metadata>
-#<Page pagenum="1" imgfile="xxx.jpg" txtfile="yyy.jpg">
+#<Page pagenum="1" imgfile="xxx.jpg" txtfile="yyy.txt">
 #<Metadata name="Title">The Title of this page</Metadata>
 #</Page>
@@ -257,5 +257,5 @@
     my $self = shift (@_);
     
-    return q^(?i)(\.jpe?g|\.gif|\.png|\.tif?f|\.te?xt|~)$^
+    return q^(?i)(\.jpe?g|\.gif|\.png|\.tif?f|\.te?xt|\.html?|~)$^
 }
 
@@ -937,9 +937,23 @@
     $text =~ s/\\/\\\\/g; # macro language
     $text =~ s/_/\\_/g; # macro language
-    $text =~ s/</&lt;/g;
-    $text =~ s/>/&gt;/g;
- 
-    # insert preformat tags and add text to document object
-    $doc_obj->add_utf8_text($cursection, "<pre>\n$text\n</pre>");
+
+
+    if ($text =~ m/<html.*?>\s*<head.*?>.*<\/head>\s*<body.*?>(.*)<\/body>\s*<\/html>\s*$/s) {
+	# looks like HTML input
+	# no need to escape < and > or put in <pre> tags
+
+	$text = $1;
+
+	# insert preformat tags and add text to document object
+	$doc_obj->add_utf8_text($cursection, "$text");
+    }
+    else {
+	$text =~ s/</&lt;/g;
+	$text =~ s/>/&gt;/g;
+
+	# insert preformat tags and add text to document object
+	$doc_obj->add_utf8_text($cursection, "<pre>\n$text\n</pre>");
+    }
+
     
     return 1;
Index: /gsdl/trunk/perllib/util.pm
===================================================================
--- /gsdl/trunk/perllib/util.pm	(revision 15017)
+++ /gsdl/trunk/perllib/util.pm	(revision 15018)
@@ -797,4 +797,46 @@
 
 
+sub locate_config_file
+{
+    my ($file) = @_;
+
+    my $locations = locate_config_files($file);
+
+    return shift @$locations; # returns undef if 'locations' is empty
+}
+
+
+sub locate_config_files
+{
+    my ($file) = @_;
+
+    my @locations = ();
+
+    if (-e $file) {
+	# Clearly specified (most likely full filename)
+	# No need to hunt in 'etc' directories, return value unchanged
+	push(@locations,$file);
+    }
+    else {
+	# Check for collection specific one before looking in global GSDL 'etc'
+
+	my $test_collect_etc_filename 
+	    = &util::filename_cat($ENV{'GSDLCOLLECTDIR'},"etc", $file);
+
+	if (-e $test_collect_etc_filename) {
+	    push(@locations,$test_collect_etc_filename);
+	}
+
+	my $test_main_etc_filename 
+	    = &util::filename_cat($ENV{'GSDLHOME'},"etc", $file);
+	if (-e $test_main_etc_filename) {
+	    push(@locations,$test_main_etc_filename);
+	}
+    }
+
+    return \@locations;
+}
+
+
 sub hyperlink_text
 {
