Index: collections/trunk/cstr/etc/collect.cfg
===================================================================
--- collections/trunk/cstr/etc/collect.cfg	(revision 14141)
+++ collections/trunk/cstr/etc/collect.cfg	(revision 14141)
@@ -0,0 +1,45 @@
+creator       sjboddie@cs.waikato.ac.nz
+maintainer    sjboddie@cs.waikato.ac.nz
+public        true
+beta          true
+
+indexes       document:text
+defaultindex  document:text
+
+macrofiles      style.dm base.dm query.dm help.dm pref.dm \
+                about.dm document.dm status.dm authen.dm \
+                users.dm html.dm extlink.dm \
+                english.dm chinese.dm french.dm german.dm maori.dm \
+                english2.dm french2.dm arabic.dm spanish.dm dutch.dm \
+		port.dm collect.dm cstr.dm
+
+
+plugin	      GMLPlug
+plugin	      PrePlug
+plugin	      ArcPlug
+plugin	      RecPlug
+
+classify      CSTRList
+
+format  SearchVList "<td valign=top>[link][icon][/link]</td><td valign=top>{If}{[parent(Top):Summary],[parent(Top):Summary],[Summary]}<br><b>Abstract:</b>{Or}{[parent(Top):Description],[Description], None}</td>"
+
+format  CL1VList "<td valign=top>[link][icon][/link]</td><td>{If}{[numleafdocs],[Title] <i>([numleafdocs])</i>,<a href=_httpcurrentdocument_&gg=postscript&gga=[cgisafe:Source]>[Source]</a>&#044; <i>[Date]</i><br>[Summary]}</td>"
+
+format  DocumentButtons  "Detach|Highlight|Expand Text"
+
+format  DocumentColumnLeft "{If}{[parent(Top):facsimiles],<a href=_httpcurrentdocument_&gg=facsimiles><img src=_httpcollimg_/_thisOID_/[parent(Top):facsimiles] width=150></a>,[parent(Top):Summary]}<br>[Buttons]"
+
+format  DocumentColumnRight "[parent(Top):Summary]<p>[TOC]"
+
+collectionmeta collectionname  "Computer Science Technical Reports"
+
+collectionmeta collectionextra "Your source for up-to-date academic computer science publications!  This collection provides an index to\ncomputer science technical reports that we have downloaded from selected sites on the Internet.  The reports are mostly in English, but\nthere are some in a variety of different languages.  The collection contains many large documents such as PhD theses.  Every single word on\nevery page of every report is indexed -- not just the first few words, as in many other search engines -- so you can search for things that\noccur near the end of the document (like references) too.\n<p>This collection contains <b>45720</b> technical reports located in <b>296</b> sites around the world. The <b>2731 Mb</b> of text is extracted from <b>34 Gb</b> of PostScript by a system developed here.  All <b>394 million</b> words from <b>1.3 million</b>\npages are indexed. The collection also contains <b>28846</b> figures extracted from the reports."
+
+collectionmeta iconcollection "_httpprefix_/collect/cstr/images/cstr.gif"
+collectionmeta iconcollectionsmall "_httpprefix_/collect/cstr/images/cstrsm.gif"
+
+collectionmeta .document:text "documents"
+
+receptionist   /cgi-bin/cstrlibrary?a=p&p=about
+
+
Index: collections/trunk/cstr/macros/cstr.dm
===================================================================
--- collections/trunk/cstr/macros/cstr.dm	(revision 14141)
+++ collections/trunk/cstr/macros/cstr.dm	(revision 14141)
@@ -0,0 +1,55 @@
+package Global
+
+_httppagehome_ [c=cstr] {/cgi-bin/library?a=p&p=home}
+
+package document
+
+_pagetitle_ [c=cstr] {_collectionname_}
+
+
+_iconpostscript_ [c=cstr] {<img name="ps" src="_httpiconepsof_" width=_widthepsx_ height=_heightepsx_ alt="_texticonpostscript_" border=0>}
+_iconpostscript_ [c=cstr,v=1] {_texticonpostscript_}
+
+_iconviewtext_ [c=cstr] {<img name="viewtext" src="_httpiconetextof_" width="_widthetextx_" height="_heightetextx_" alt="_texticonviewtext_" border="0">}
+_iconviewtext_ [c=cstr,v=1] {_texticonviewtext_}
+
+_iconabstract_ [c=cstr] {<img name="abstract" src="_httpiconeabstrof_" width="_widtheabstrx_" height="_heighteabstrx_" alt="_texticonabstract_" border="0">}
+_iconabstract_[c=cstr,v=1] {_texticonabstract_}
+
+_iconfigures_ [c=cstr] {<img name="figures" src="_httpiconefigof_" width="_widthefigx_" height="_heightefigx_" alt="_texticonfigures_" border="0">}
+_iconfigures_ [c=cstr,v=1] {_texticonfigures_}
+
+
+
+_imagepostscript_ [c=cstr] {_gsimage_(_httpcurrentdocument_&gg=postscript&gga=_1_,_document:httpiconepsof_,_document:httpiconepson_,ps,_document:texticonpostscript_)}
+
+_imageviewtext_ [c=cstr] {_gsimage_(_httpcurrentdocument_&gg=text,_document:httpiconetextof_,_document:httpiconetexton_,etext,_document:texticonviewtext_)}
+
+_imageabstract_ [c=cstr] {_gsimage_(_httpcurrentdocument_&gg=abstract,_document:httpiconeabstrof_,_document:httpiconeabstron_,eabstr,_document:texticonabstract_)}
+
+_imagefigures_ [c=cstr] {_gsimage_(_httpcurrentdocument_&gg=figures,_document:httpiconefigof_,_document:httpiconefigon_,fig,_document:texticonfigures_)}
+
+_httpiconepsof_ [c=cstr] {_httpprefix_/collect/cstr/images/epsof.gif}
+_httpiconepson_ [c=cstr] {_httpprefix_/collect/cstr/images/epson.gif}
+_widthepsx_ [c=cstr] {64}
+_heightepsx_ [c=cstr] {30}
+
+_httpiconetextof_ [c=cstr] {_httpprefix_/collect/cstr/images/etextof.gif}
+_httpiconetexton_ [c=cstr] {_httpprefix_/collect/cstr/images/etexton.gif}
+_widthetextx_ [c=cstr] {65}
+_heightetextx_ [c=cstr] {30}
+
+_httpiconeabstrof_ [c=cstr] {_httpprefix_/collect/cstr/images/eabstrof.gif}
+_httpiconeabstron_ [c=cstr] {_httpprefix_/collect/cstr/images/eabstron.gif}
+_widtheabstrx_ [c=cstr] {65}
+_heighteabstrx_ [c=cstr] {30}
+
+_httpiconefigof_ [c=cstr] {_httpprefix_/collect/cstr/images/efigof.gif}
+_httpiconefigon_ [c=cstr] {_httpprefix_/collect/cstr/images/efigon.gif}
+_widthefigx_ [c=cstr] {47}
+_heightefigx_ [c=cstr] {30}
+
+_texticonpostscript_ [c=cstr] {Download postscript of this document}
+_texticonviewtext_ [c=cstr] {View the text of this page}
+_texticonabstract_ [c=cstr] {View the abstract of this document}
+_texticonfigures_ [c=cstr] {View figures extracted from document postscript}
Index: collections/trunk/cstr/perllib/classify/CSTRList.pm
===================================================================
--- collections/trunk/cstr/perllib/classify/CSTRList.pm	(revision 14141)
+++ collections/trunk/cstr/perllib/classify/CSTRList.pm	(revision 14141)
@@ -0,0 +1,95 @@
+###########################################################################
+#
+# CSTRList.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# hacked about version of List classifier for use with cstr collection. 
+# Creates list of Source's (ftp sites), each of which contains a list of
+# those documents originating from Source.
+
+# note that 'Source' metadata contains entire path to document so
+# we strip it down to get the ftp site.
+
+package CSTRList;
+
+use sorttools;
+
+sub new {
+    my ($class, @options) = @_;
+
+    my $listname = &util::filename_cat($ENV{'GSDLHOME'},"perllib/classify/List.pm"); 
+    if (-e $listname) { require $listname; }
+    else { die "CSTRList ERROR - couldn't find classifier \"$listname\"\n"; }
+
+    return bless {
+	'list'=>{},
+    }, $class;
+}
+
+sub init {
+    my $self = shift (@_);
+    $self->{'list'} = {};
+}
+
+sub classify {
+    my $self = shift (@_);
+    my ($doc_obj) = @_;
+
+    my $doc_OID = $doc_obj->get_OID();
+
+    my $source = $doc_obj->get_metadata_element ($doc_obj->get_top_section(), 'Source');
+
+    if (defined $source) {
+	my ($ftp_site) = $source =~ /^((ftp:\/\/)?([^\/\\]*))/;
+	print STDERR "CSTRList: Warning: ftp_site undefined\n" unless defined $ftp_site;
+	if (!defined ($self->{'list'}->{$ftp_site})) {
+	    my ($listclassobj);
+	    eval ("\$listclassobj = new List(\"sort=Date\", \"title=\$ftp_site\")");
+	    die "$@" if $@;
+	    $listclassobj->init();
+	    $self->{'list'}->{$ftp_site} = $listclassobj;
+	    $self->{'list'}->{$ftp_site}->classify ($doc_obj);
+	} else {
+	    $self->{'list'}->{$ftp_site}->classify ($doc_obj);
+	}	    
+    }
+}
+
+sub get_classify_info {
+    my $self = shift (@_);
+
+    # organise into classification structure
+    my %classifyinfo = ('thistype'=>'Invisible',
+			'childtype'=>'VList',
+			'Title'=>'Browse',
+			'contains'=>[]);
+    foreach $ftp_site (sort keys %{$self->{'list'}}) {
+	push (@{$classifyinfo{'contains'}}, 
+	      $self->{'list'}->{$ftp_site}->get_classify_info());
+    }
+    
+    return \%classifyinfo;
+}
+
+
+1;
Index: collections/trunk/cstr/perllib/plugins/PrePlug.pm
===================================================================
--- collections/trunk/cstr/perllib/plugins/PrePlug.pm	(revision 14141)
+++ collections/trunk/cstr/perllib/plugins/PrePlug.pm	(revision 14141)
@@ -0,0 +1,284 @@
+###########################################################################
+#
+# PrePlug.pm --
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+# plugin that processes simple html files like those output 
+# by prescript when converting postscript to html. 
+# prescript output has <p> tags separating paragraphs
+# and <!--End Of Page--> tags separating pages.
+# it may also have <!--Page No--> tags at top or bottom of 
+# some or all pages.
+
+# if a .html1 version of a .html file exists then that version 
+# will be used so that the author name can be extracted
+# (.html1 files were generated by software which automatically 
+# extracts author names from .html files).
+
+# also looks for a .info file containing metadata (as used by 
+# the cstr collection)
+
+package PrePlug;
+
+use BasPlug;
+use sorttools;
+
+sub BEGIN {
+    @ISA = ('BasPlug');
+}
+
+sub new {
+    my ($class) = @_;
+    $self = new BasPlug ();
+
+    return bless $self, $class;
+}
+
+sub is_recursive {
+    my $self = shift (@_);
+
+    return 0; # this is not a recursive plugin
+}
+
+
+# return number of files processed, undef if can't process
+# Note that $base_dir might be "" and that $file might 
+# include directories
+sub read {
+    my $self = shift (@_);
+    my ($pluginfo, $base_dir, $file, $metadata, $processor) = @_;
+
+    my $filename = &util::filename_cat($base_dir, $file);
+
+    return 0 if ($filename =~ /\.(html1|html1\.gz|info|gif)/);
+
+    return undef unless ($filename =~ /\.(html(\.gz)?)$/i && (-e $filename));
+
+    my $gz = 0;
+    $gz = 1 if (defined $2 && $2 eq ".gz");
+
+    my $filename1 = $filename;
+    if ($gz) {
+	$filename1 =~ s/\.html\.gz$/\.html1\.gz/;
+    } else {
+	$filename1 .= "1";
+    }
+    
+    $filename = $filename1 if (-e $filename1);
+
+    print STDERR "PrePlug: processing $filename\n" if $processor->{'verbosity'};
+
+    # create a new document
+    my $doc_obj = new doc ($file, "indexed_doc");
+
+    if ($gz) {
+	open (FILE, "zcat $filename |") || die "PrePlug::read - zcat can't open $filename\n";
+    } else {
+	open (FILE, $filename) || die "PrePlug::read - can't open $filename\n";
+    }
+    my $cursection = $doc_obj->get_top_section();
+
+    my $text = "";
+    my $line = "";
+    my $pagenumber = 1;
+    my @creators = ();
+    my $numlines = 0;
+    while (defined ($line = <FILE>)) {
+	if ($filename =~ /html1$/) {
+	    while ($text =~ s/<_author_search_\([^\)]*\)>([^<]*)<\/a>/$1/i) {
+		push (@creators, $1);
+	    }
+	}
+
+	# numlines sorts out documents that just have a single <!-- End of Page--> tag at the end
+	if ($line =~ /<!--End\s+Of\s+Page-->/i && $numlines < 200) {
+
+	    $numlines = -1000;
+	    $cursection = 
+		$doc_obj->insert_section($doc_obj->get_end_child($doc_obj->get_top_section()));
+
+	    $text =~ s/<!--Page No-->\s*<p>\s*<center>\s*<b>\s*(\d+)<\/b>\s*<\/center>\s*//i;
+#	    if (defined $1 && $1 != $pagenumber) {
+#		print STDERR "PrePlug Warning: Pagenumbers don't line up in $filename\n";
+#	    }
+	    $doc_obj->add_text ($cursection, $text);
+	    $doc_obj->add_metadata ($cursection, "Title", $pagenumber);
+	    $pagenumber ++;
+	    $text = "";
+	} else {
+	    $text .= $line;
+	    $numlines ++; 
+	}
+    }
+    close FILE;
+
+    if ($cursection eq $doc_obj->get_top_section()) {
+	# there weren't any <!--End Of Page--> tags
+	
+	# see if there were any <!--Page No--> tags to split on
+	if ($text =~ /<!--Page No-->/i) {
+	    while ($text =~ s/^(.*?)<!--Page No-->\s*<p>\s*<center>\s*<b>\s*\d+<\/b>\s*<\/center>\s*//i) {
+		$cursection = 
+		    $doc_obj->insert_section($doc_obj->get_end_child($doc_obj->get_top_section()));
+		$doc_obj->add_text ($cursection, $text);
+		$doc_obj->add_metadata ($cursection, "Title", $pagenumber);
+		$pagenumber ++;
+	    }
+	}
+	# otherwise we'll just have to split pages on set number of lines
+	else {
+	    my $pagetext = "";
+	    my $line = "";
+	    my $count = 0;
+	    while (length ($text) && $text =~ s/^(.*?)(\n|$)//) {
+		$line = $1;
+		$line = "" unless defined $line;
+		$pagetext .= $line . "\n";
+		if (($count >= 50 && $line !~ /\w/) || $count == 80) {
+		    $cursection = 
+			$doc_obj->insert_section($doc_obj->get_end_child($doc_obj->get_top_section()));
+		    $doc_obj->add_text ($cursection, $pagetext);
+		    $doc_obj->add_metadata ($cursection, "Title", $pagenumber);
+		    $pagetext = "";
+		    $pagenumber ++;
+		    $count = 0;
+		} else {
+		    $count ++;
+		}
+	    }
+	}
+	    
+    }
+	    
+    # final section
+    if ($text =~ /\w/) {
+	$cursection = 
+	    $doc_obj->insert_section($doc_obj->get_end_child($doc_obj->get_top_section()));
+	
+	$text =~ s/<!--Page No-->\s*<p>\s*<center>\s*<b>\s*(\d+)<\/b>\s*<\/center>\s*//;
+#	if (defined $1 && $1 != $pagenumber) {
+#	    print STDERR "PrePlug Warning: Pagenumbers don't line up in $filename\n";
+#	}
+	$doc_obj->add_text ($cursection, $text);
+	$doc_obj->add_metadata ($cursection, "Title", $pagenumber);
+    }
+
+    # add meta data for top level of document
+    map {$doc_obj->add_metadata ($doc_obj->get_top_section(), "Creator", $_)} @creators;
+
+    my ($filesuff) = $filename =~ /^(.*?)\.html1?/;
+    if (!-e $filesuff . ".info") {
+	print STDERR "Preplug Warning: $filename has no corresponding .info file\n";
+    } else {
+	my ($dir) = $filesuff =~ /^(.*?)~?[^~]*$/;
+	open (INFO, $filesuff . ".info") || die "PrePlug::read - can't open $filesuff.info\n";
+	my $line = "";
+	while (defined ($line = <INFO>)) {
+	    chop $line;
+	    my ($key, $value) = $line =~ /^<([^>]*)>(.*)$/;
+	    next if $key =~ /^(pages|compressedsize|\/?info|size)$/i;
+	    next if $value !~ /\w/;
+	    if ($key =~ /^abstract$/i) {
+		$key = "Description";
+	    } elsif ($key =~ /^url$/i) {
+		$key = "Source";
+	    } elsif ($key =~ /^filedate$/i) {
+		$key = "Date";
+		my ($day, $month, $year) = split /\//, $value;
+		$value = &sorttools::format_date ($day, $month, $year);
+	    } elsif ($key =~ /^transferdate$/i) {
+		my ($day, $month, $year) = split /\//, $value;
+		$value = &sorttools::format_date ($day, $month, $year);
+	    } elsif ($key =~ /^facsimiles$/i) {
+		$value =~ s/^\s+//;
+		$value =~ s/\s+$//;
+		my @facsimiles = split /\s+/, $value;
+		foreach $facsimile (@facsimiles) {
+		    # assume images are in the same directory
+		    my $imagefile = $dir . "~" . $facsimile;
+		    if (-e $imagefile) {
+			my ($imagetype) = $facsimile =~ /\.([^\.]*)$/;
+			$doc_obj->associate_file($imagefile, $facsimile, "image/" . $imagetype);
+			# add metadata for each facsimile
+			$doc_obj->add_metadata ($doc_obj->get_top_section(), $key, $facsimile);
+		    } else {
+			print STDERR "PrePlug: Warning - facsimile file $imagefile doesn't exist\n";
+		    }
+		}
+		# we've already added facsimile metadata
+		next;
+
+	    } elsif ($key =~ /^figures$/i) {
+		$value =~ s/^\s+//;
+		$value =~ s/\s+$//;
+		my @figures = split /\s+/, $value;
+		foreach $figure (@figures) {
+		    # assume images are in the same directory
+		    my $imagefile = $dir . "~" . $figure;
+		    if (-e $imagefile) {
+			my ($imagetype) = $figure =~ /\.([^\.]*)$/;
+			$doc_obj->associate_file($imagefile, $figure, "image/" . $imagetype);
+		    } else {
+			print STDERR "PrePlug: Warning - figure file $imagefile doesn't exist\n";
+			next;
+		    }
+		    $value = join ",", @figures;
+		}
+	    }
+	    $doc_obj->add_metadata ($doc_obj->get_top_section(), $key, $value);
+	}
+	close INFO;
+    }
+
+    foreach $field (keys(%$metadata)) {
+	# $metadata->{$field} may be an array reference
+	if (ref ($metadata->{$field}) eq "ARRAY") {
+	    map { 
+		$doc_obj->add_metadata ($doc_obj->get_top_section(), $field, $_); 
+	    } @{$metadata->{$field}};
+	} else {
+	    $doc_obj->add_metadata ($doc_obj->get_top_section(), $field, $metadata->{$field}); 
+	}
+    }
+
+    # add OID
+    $doc_obj->set_OID ();
+
+    # process the document
+    $processor->process($doc_obj);
+
+    return 1; # processed the file
+}
+
+1;
+
+
+
+
+
+
+
+
+
+
+
Index: collections/trunk/cstr/src/recpt/Makefile.in
===================================================================
--- collections/trunk/cstr/src/recpt/Makefile.in	(revision 14141)
+++ collections/trunk/cstr/src/recpt/Makefile.in	(revision 14141)
@@ -0,0 +1,161 @@
+###########################################################################
+#
+# Makefile -- Makefile for cstrlibrary
+# A component of the Greenstone digital library software
+# from the New Zealand Digital Library Project at the 
+# University of Waikato, New Zealand.
+#
+# Copyright (C) 1999 New Zealand Digital Library Project
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+###########################################################################
+
+GD = ../../../..
+MAINRECPTDIR = $(GD)/src/recpt
+MAINCOLSERVRDIR = $(GD)/src/colservr
+
+AR = ar
+CC = @CC@
+CCFLAGS = @CFLAGS@ -Wall -Wunused -pedantic -W -Woverloaded-virtual
+DEFS = -DNZDL -DQUIET -DSHORT_SUFFIX -DPARADOCNUM -DGSDLSERVER \
+       -D_LITTLE_ENDIAN -DGSDLSERVER @DEFS@
+
+USE_FASTCGI = @USE_FASTCGI@
+ifneq ($(USE_FASTCGI), 1)
+INCLUDES = -I$(MAINRECPTDIR) -I$(MAINCOLSERVRDIR) -I$(GD)/lib \
+	   -I$(GD)/packages/mg -I$(GD)/packages/mg/lib -I$(GD)/packages/mg/src/text 
+else
+INCLUDES = -I$(MAINRECPTDIR) -I$(MAINCOLSERVRDIR) -I$(GD)/lib \
+	   -I$(GD)/packages/mg -I$(GD)/packages/mg/lib -I$(GD)/packages/mg/src/text \
+           -I$(GD)/packages/fcgi/include
+endif
+
+RANLIB = @RANLIB@
+LDFLAGS = @LDFLAGS@
+#LIBS = -lgdbm -lstdc++ -lm -lcrypt
+LIBS = @LIBS@
+
+GSDLOS = @gsdlos@
+
+
+COMPILE = $(CC) -c $(CCFLAGS) $(DEFS) $(INCLUDES)
+LINK = $(CC) $(LDFLAGS) -o $@
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+.c.o:
+	$(COMPILE) $<
+
+.SUFFIXES: .cpp .o
+.cpp.o:
+	$(COMPILE) $< 
+
+
+HEADERS = cstrdocaction.h cstrbrowsetools.h cstrpagedbrowserclass.h
+
+SOURCES = cstrlibrarymain.cpp cstrdocaction.cpp cstrbrowsetools.cpp \
+	  cstrpagedbrowserclass.cpp
+
+
+OBJECTS = cstrlibrarymain.o cstrdocaction.o cstrbrowsetools.o \
+	  cstrpagedbrowserclass.o
+
+
+EXEC    = cstrlibrary
+
+all : $(EXEC)
+
+install:
+	install -m 755 -s $(EXEC) $(GD)/cgi-bin/$(EXEC)
+
+clean:
+	rm -f $(OBJECTS) $(EXEC)
+
+depend:
+	makedepend -Y -- $(DEFS) $(INCLUDES) $(CCFLAGS) -- $(SOURCES)
+
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+
+CSTRLIBRARY_OBJS = $(OBJECTS) \
+    $(MAINRECPTDIR)/querytools.o \
+    $(MAINRECPTDIR)/browsetools.o \
+    $(MAINRECPTDIR)/browserclass.o \
+    $(MAINRECPTDIR)/vlistbrowserclass.o \
+    $(MAINRECPTDIR)/hlistbrowserclass.o \
+    $(MAINRECPTDIR)/datelistbrowserclass.o \
+    $(MAINRECPTDIR)/invbrowserclass.o \
+    $(MAINRECPTDIR)/pagedbrowserclass.o \
+    $(MAINRECPTDIR)/htmlbrowserclass.o \
+    $(MAINRECPTDIR)/receptionist.o \
+    $(MAINRECPTDIR)/recptconfig.o \
+    $(MAINRECPTDIR)/cgiwrapper.o \
+    $(MAINRECPTDIR)/cgiargs.o \
+    $(MAINRECPTDIR)/action.o \
+    $(MAINRECPTDIR)/converter.o \
+    $(MAINRECPTDIR)/cgiutils.o \
+    $(MAINRECPTDIR)/OIDtools.o \
+    $(MAINRECPTDIR)/htmlgen.o \
+    $(MAINRECPTDIR)/statusaction.o \
+    $(MAINRECPTDIR)/pageaction.o \
+    $(MAINRECPTDIR)/comtypes.o \
+    $(MAINRECPTDIR)/recptproto.o \
+    $(MAINRECPTDIR)/pingaction.o \
+    $(MAINRECPTDIR)/queryaction.o \
+    $(MAINRECPTDIR)/documentaction.o \
+    $(MAINRECPTDIR)/htmlutils.o \
+    $(MAINRECPTDIR)/nullproto.o \
+    $(MAINRECPTDIR)/infodbclass.o \
+    $(MAINRECPTDIR)/formattools.o \
+    $(MAINRECPTDIR)/tipaction.o \
+    $(MAINRECPTDIR)/authenaction.o \
+    $(MAINRECPTDIR)/usersaction.o \
+    $(MAINRECPTDIR)/userdb.o \
+    $(MAINRECPTDIR)/historydb.o \
+    $(MAINCOLSERVRDIR)/mgq.o \
+    $(MAINCOLSERVRDIR)/querycache.o \
+    $(MAINCOLSERVRDIR)/queryinfo.o \
+    $(MAINCOLSERVRDIR)/collectserver.o \
+    $(MAINCOLSERVRDIR)/colservrconfig.o \
+    $(MAINCOLSERVRDIR)/maptools.o \
+    $(MAINCOLSERVRDIR)/filter.o \
+    $(MAINCOLSERVRDIR)/source.o \
+    $(MAINCOLSERVRDIR)/browsefilter.o \
+    $(MAINCOLSERVRDIR)/queryfilter.o \
+    $(MAINCOLSERVRDIR)/mgqueryfilter.o \
+    $(MAINCOLSERVRDIR)/mgppqueryfilter.o \
+    $(MAINCOLSERVRDIR)/phrasesearch.o \
+    $(MAINCOLSERVRDIR)/mggdbmsource.o \
+    $(MAINCOLSERVRDIR)/search.o \
+    $(MAINCOLSERVRDIR)/mgsearch.o \
+    $(MAINCOLSERVRDIR)/mgppsearch.o \
+    $(MAINCOLSERVRDIR)/collectset.o \
+    $(GD)/lib/gsdllib.a  \
+    $(GD)/packages/mg/src/text/libtextin.a \
+    $(GD)/packages/mg/lib/libmg.a \
+    $(GD)/src/mgpp/text/libtextin.a \
+    $(GD)/src/mgpp/lib/libmg.a
+
+
+ifneq ($(USE_FASTCGI), 1)
+CSTRLIB_OBJS = $(CSTRLIBRARY_OBJS)
+else
+CSTRLIB_OBJS = $(CSTRLIBRARY_OBJS) $(GD)/packages/fcgi/libfcgi/libfcgi.a
+endif
+
+cstrlibrary: $(CSTRLIB_OBJS)
+	$(LINK) $(CSTRLIB_OBJS) $(LIBS) 
Index: collections/trunk/cstr/src/recpt/cstrbrowsetools.cpp
===================================================================
--- collections/trunk/cstr/src/recpt/cstrbrowsetools.cpp	(revision 14141)
+++ collections/trunk/cstr/src/recpt/cstrbrowsetools.cpp	(revision 14141)
@@ -0,0 +1,246 @@
+/**********************************************************************
+ *
+ * cstrbrowsetools.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+#include "cstrbrowsetools.h"
+#include "OIDtools.h"
+#include "cgiutils.h"
+#include "browsetools.h"
+
+
+
+// outputs the postscript, abstract, figures etc buttons
+static void output_cstr_controls (cgiargsclass &args, const text_t &source, 
+				  const text_t &description, const text_t &figures, 
+				  displayclass &disp, outconvertclass &outconvert, 
+				  ostream &textout) {
+  text_tarray buttons;
+  text_t &arg_gg = args["gg"];
+  
+  if (!source.empty())
+    buttons.push_back ("_document:imagepostscript_(" + cgi_safe(source) + ")");
+
+  if ((!description.empty()) && (arg_gg != "abstract"))
+    buttons.push_back ("_document:imageabstract_");
+
+  if ((!figures.empty()) && (arg_gg != "figures"))
+    buttons.push_back ("_document:imagefigures_");
+
+  if (arg_gg != "text")
+    buttons.push_back ("_document:imageviewtext_");
+
+  textout << "<br>\n";
+
+  text_tarray::const_iterator here = buttons.begin();
+  text_tarray::const_iterator end = buttons.end();
+  int count = 0;
+  while (here != end) {
+    if ((count != 0) && ((count % 3) == 0)) textout << "<br>\n";
+    textout << outconvert << disp << *here;
+    count ++;
+    here ++;
+  }
+}
+
+
+
+void output_cstr_toc (cgiargsclass &args, browsermapclass *browsermap,
+                 formatinfo_t &formatinfo, recptproto *collectproto,
+                 displayclass &disp, outconvertclass &outconvert,
+				ostream &textout, ostream &logout) {
+
+  int tabcount = 0;
+  bool havecontrols = false;
+  bool fulltoc = false;
+
+
+  if (args["cl"] != "search") {
+    // see if there's a FullTOC string
+    text_t cl_top, full_toc;
+    get_top (args["cl"], cl_top);
+    if (get_formatstring (cl_top, "FullTOC", formatinfo.formatstrings, full_toc))
+      if (full_toc == "true") fulltoc = true;
+  }
+  text_t &arg_d = args["d"];
+  // get the facsimile image (if there is one) and the control buttons
+  // if we're inside a book
+  if ((!fulltoc) && (!arg_d.empty())) {
+
+    // this code from old cstr browsetools outputdocument_toc
+    text_tset metadata;
+    FilterResponse_t response;
+    ResultDocInfo_t docinfo;
+    text_t booktop, facsimiles, figures, description, source, summary;
+    text_t &collection = args["c"];
+
+    metadata.insert ("Title");
+    if (get_info (arg_d, collection, metadata, false, collectproto, response, logout)) {
+
+      metadata.erase (metadata.begin(), metadata.end());
+      docinfo = response.docInfo[0];
+      
+      textout 
+	<< "\n<!-- Table of Contents produced by cstrbrowsetools::output_document_toc -->\n\n";
+
+      // get title and author of book
+      get_top (arg_d, booktop);
+      metadata.insert ("facsimiles");
+      metadata.insert ("figures");
+      metadata.insert ("Description");
+      metadata.insert ("Source");
+      metadata.insert ("Summary");
+      get_info (booktop, collection, metadata, false, collectproto, response, logout);
+      facsimiles = response.docInfo[0].metadata["facsimiles"].values[0];
+      figures = response.docInfo[0].metadata["figures"].values[0];
+      description = response.docInfo[0].metadata["Description"].values[0];
+      source = response.docInfo[0].metadata["Source"].values[0];
+      summary = response.docInfo[0].metadata["Summary"].values[0];
+
+      metadata.erase (metadata.begin(), metadata.end());
+  
+      textout << outconvert << disp 
+	      << "<p><center>\n"
+	      << "<table cellpadding=0 cellspacing=0 width=_pagewidth_>\n"
+	      << "<tr valign=top><td>\n";
+
+      /*      
+      // don't want arrows and page number if text expanded
+      if (formatinfo.DocumentArrowsBottom && !args.getintarg ("gt")) {
+    
+	// previous arrow
+	textout << outconvert << disp << "<table><tr valign=top>\n"
+		<< "<td align=left>_document:prevarrow_</td>\n";
+    
+	// page ? of ? text
+	textout << "<td align=center>\n";
+	
+	if (is_number (docinfo.metadata["Title"].values[0])) {
+	  text_t doctop;
+	  metadata.insert ("Title");
+	  get_top (arg_d, doctop);
+	  // get title of last sibling
+	  if (get_info (doctop + ".lc", collection, metadata, false, collectproto, response, logout)) {
+	    if (is_number (response.docInfo[0].metadata["Title"].values[0])) {
+	      textout << outconvert << disp << "_document:page_" << docinfo.metadata["Title"].values[0]
+		      << "_document:of_" << response.docInfo[0].metadata["Title"].values[0];
+	    } else {
+	      textout << outconvert << docinfo.metadata["Title"].values[0];
+	    }
+	  }
+	} else {
+	  textout << outconvert << docinfo.metadata["Title"].values[0];
+      }
+  
+	// next arrow
+	textout << outconvert << disp << "</td>\n<td align=right>_document:nextarrow_</td>\n</table>\n";
+      }
+      
+      // goto line ****** ????????????
+      //if (formatinfo.DocumentGoTo)
+      textout << outconvert << disp << "_document:gotoform_";
+      */
+
+      //if (formatinfo.DocumentArrowsBottom && !args.getintarg ("gt")) {
+	if (args.getintarg("gc") == 1) {
+	
+	  // expanded table of contents
+	  expanded_contents (args, tabcount, fulltoc, browsermap, formatinfo, 
+			     collectproto, disp, outconvert, textout, logout);
+	} else {
+	  
+	  // contracted table of contents
+	  contracted_contents (args, tabcount, fulltoc, browsermap, formatinfo, 
+			       collectproto, disp, outconvert, textout, logout);
+	}
+	// }
+      // control buttons
+      output_controls (args, formatinfo.DocumentButtons, collectproto, 
+		       disp, outconvert, textout, logout);
+      textout << "</td><td valign=top>\n";
+
+      if (!summary.empty())
+	textout << outconvert << summary << "\n";
+
+      output_cstr_controls (args, source, description, figures, 
+			    disp, outconvert, textout);
+
+      textout << "</td>\n";
+    
+      // facsimile image
+      // only want the first facsimile (some documents have two)
+      if (!facsimiles.empty()) {
+	text_t::const_iterator fbegin = facsimiles.begin();
+	facsimiles = substr (fbegin, findchar (fbegin, facsimiles.end(), ','));
+	textout << outconvert << disp << "<td valign=top><a href=\"_httpcurrentdocument_&gg=facsimiles\">"
+		<< "<img src=\"_httpprefix_/collect/cstr/index/assoc/_thisOID_/" 
+		<< facsimiles << "\" width=150 height=250></a>" << "</td>\n";
+      }
+      
+
+      textout << "</td></tr></table></center>\n";
+      textout << "\n<!-- end of Table of Contents -->\n";
+      
+    }
+
+    /*    textout << "<p><table cellpadding=0 cellspacing=0><tr>\n";
+    textout << "<td valign=top";
+    if (formatinfo.DocumentContents) textout << " width=200>\n";
+    else textout << " width=100%>\n";
+    if (formatinfo.DocumentImages) 
+      output_cover_image (args, collectproto, disp, outconvert, textout, logout);
+    else if (formatinfo.DocumentTitles)
+      output_titles (args, collectproto, formatinfo, disp, outconvert, textout, logout);
+    output_controls (args, formatinfo.DocumentButtons, collectproto, disp, 
+		     outconvert, textout, logout);
+    textout << "</td><td valign=top>\n";
+    havecontrols = true; */
+  }
+  /*
+  if (formatinfo.DocumentContents || args["d"].empty()) {
+    if (args.getintarg("gc") == 1) {
+      
+      // expanded table of contents
+      expanded_contents (args, tabcount, fulltoc, browsermap, formatinfo, 
+			 collectproto, disp, outconvert, textout, logout);
+    } else {
+      
+      // contracted table of contents
+      contracted_contents (args, tabcount, fulltoc, browsermap, formatinfo, 
+			   collectproto, disp, outconvert, textout, logout);
+    }
+  }
+  */
+  if (havecontrols) textout << "</td></tr></table>\n";
+}
+
+
+
+
+
+
+
+
+
Index: collections/trunk/cstr/src/recpt/cstrbrowsetools.h
===================================================================
--- collections/trunk/cstr/src/recpt/cstrbrowsetools.h	(revision 14141)
+++ collections/trunk/cstr/src/recpt/cstrbrowsetools.h	(revision 14141)
@@ -0,0 +1,47 @@
+/**********************************************************************
+ *
+ * cstrbrowsetools.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+
+#ifndef CSTRBROWSETOOLS_H
+#define CSTRBROWSETOOLS_H
+
+#include "gsdlconf.h"
+#include "text_t.h"
+#include "cgiargs.h"
+#include "display.h"
+#include "recptproto.h"
+#include "formattools.h"
+#include "browsetools.h"
+
+void output_cstr_toc (cgiargsclass &args, browsermapclass *browsermap,
+                 formatinfo_t &formatinfo, recptproto *collectproto,
+                 displayclass &disp, outconvertclass &outconvert,
+                 ostream &textout, ostream &logout);
+
+
+#endif
+
Index: collections/trunk/cstr/src/recpt/cstrdocaction.cpp
===================================================================
--- collections/trunk/cstr/src/recpt/cstrdocaction.cpp	(revision 14141)
+++ collections/trunk/cstr/src/recpt/cstrdocaction.cpp	(revision 14141)
@@ -0,0 +1,497 @@
+/**********************************************************************
+ *
+ * cstrdocaction.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+/*
+   $Log$
+   Revision 1.4  2001/05/30 01:39:18  sjboddie
+   Rewound cstr to use the old browsetools etc approach rather than the
+   LeftColumn etc methods
+
+   Revision 1.2  2000/02/06 21:25:21  sjboddie
+   updated cstr
+
+   Revision 1.1  1999/09/07 21:49:42  sjboddie
+   new cstr receptionist
+
+ */
+
+
+#include <string.h>
+#include "cstrdocaction.h"
+#include "cstrbrowsetools.h"
+#include "browsetools.h"
+#include "OIDtools.h"
+#include "querytools.h"
+#include "unitool.h"
+
+cstrdocaction::cstrdocaction () {
+  // this action uses cgi variable "gg" and "gga" as well as
+  // those used by the standard documentaction
+
+  cgiarginfo arg_ainfo;
+
+  // in this action "gg" is the format of the
+  // document to view (i.e. "text", "postscript", "abstract", "figures", or "facsimiles")
+  arg_ainfo.shortname = "gg";
+  arg_ainfo.longname = "document format";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "text";
+  arg_ainfo.savedarginfo = cgiarginfo::can;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // in this action "gga" is the path to the postscript
+  // when "gg" == "postscript
+  arg_ainfo.shortname = "gga";
+  arg_ainfo.longname = "postscript path";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::none;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+}
+
+cstrdocaction::~cstrdocaction () {
+}
+
+
+void cstrdocaction::get_cgihead_info (cgiargsclass &args, recptprotolistclass * /*protos*/,
+				      response_t &response,text_t &response_data, 
+				      ostream &/*logout*/) {
+
+  if (args["gg"] == "postscript") {
+    response = location;
+    response_data = args["gga"];
+  } else {
+    response = content;
+    response_data = "text/html";
+  }
+}
+
+
+void cstrdocaction::set_java_macros (cgiargsclass &args, displayclass &disp) {
+
+  text_t javaimagescontent = "<!----java images content------->\n_javaextras__javapostscript_";
+
+  text_t &arg_gg = args["gg"];
+  if (arg_gg == "text")
+    javaimagescontent += "_javaabstract__javafigures_";
+  else if (arg_gg == "abstract")
+    javaimagescontent += "_javafigures__javaviewtext_";
+  else if (arg_gg == "figures")
+    javaimagescontent += "_javaabstract__javaviewtext_";
+  else if (arg_gg == "facsimiles")
+    javaimagescontent += "_javaabstract__javaviewtext__javafigures_";
+	
+  int arg_gt = args.getintarg("gt");
+  //  int arg_gc = args.getintarg("gc");
+  int arg_hl = args.getintarg("hl");
+
+  text_tarray::const_iterator button_here = formatinfo.DocumentButtons.begin();
+  text_tarray::const_iterator button_end = formatinfo.DocumentButtons.end();
+
+  while (button_here != button_end) {
+    if (*button_here == "Detach") 
+      javaimagescontent += "_javadetach_";
+    else if (*button_here == "Expand Text" && arg_gg == "text") {
+      if (arg_gt == 1)
+	javaimagescontent += "_javacontracttext__javacontinue_";
+      else if (arg_gt == 2)
+	javaimagescontent += "_javacontracttext_";
+      else
+	javaimagescontent += "_javaexpandtext_";
+      //    } else if (*button_here == "Expand Contents") {
+      //      if (arg_gc == 1)
+      //	javaimagescontent += "_javacontractcontents_";
+      //      else
+      //	javaimagescontent += "_javaexpandcontents_";
+    } else if (*button_here == "Highlight" && arg_gg == "text") {
+      if (arg_hl == 1)
+	javaimagescontent += "_javanohighlighting_";
+      else 
+	javaimagescontent += "_javahighlighting_";
+    }
+    button_here ++;
+  }
+  javaimagescontent += "<!--end java img content--->\n";
+  disp.setmacro ("javaimagescontent", "document", javaimagescontent);
+}
+
+
+
+/*
+// define all the macros which are related to pages generated
+// by this action. we also load up the formatinfo structure 
+// here (it's used in do_action as well as here)
+void cstrdocaction::define_internal_macros (const ColInfoResponse_t &collectinfo, displayclass &disp, 
+					    cgiargsclass &args, recptproto *collectproto, 
+					    ostream &logout) {
+  
+  // define_internal_macros sets the following macros:
+
+  // _pagetitle_            the title to be displayed at the top of the browser window
+  
+  // _imagethispage_        the title image to be displayed at top right of page
+  
+  // _classificationlinks_  the links between classifications to be displayed
+  //                        at top of list or datelist classifications
+
+  // _httpprevarrow_        these are set if next or previous arrows
+  // _httpnextarrow_        are to be used - (i.e. if it's an AZList or a DateList 
+  //                        classifytype at a top level or if it's a Book or a
+  //                        Hierarchy classifytype at document level 
+
+  // _navarrows_            this may be overridden to "" when format option 
+  //                        DocumentArrowsBottom is false
+
+  // _header_               the header macro is overridden if we're not at a top level 
+  //                        classification to remove the title block
+
+  // _javaimagescontent_    this is the javascript code to shove in to make the 
+  //                        flashy buttons work
+
+  // _thisOID_              the OID (directory) of the current document - this corresponds
+  //                        to the archivedir metadata element
+
+  // can't do anything if collectproto is null (i.e. no collection was specified)
+  if (collectproto == NULL) return;
+  
+  text_tarray metadata;
+  FilterResponse_t response;
+  text_t &arg_d = args["d"];
+  text_t &arg_cl = args["cl"];
+  text_t &collection = args["c"];
+  int gt = args.getintarg("gt");
+  load_formatinfo (collectinfo.format, gt);
+
+  // don't want arrows or goto if we're in figures or facsimiles
+  if (args["gg"] != "text") {
+    formatinfo.DocumentArrowsBottom = false;
+    formatinfo.DocumentArrowsTop = false;
+    formatinfo.DocumentGoTo = false;
+  }
+
+  if (!formatinfo.DocumentArrowsBottom)
+    disp.setmacro("navarrows", "document", "");
+
+  metadata.push_back ("Title");
+  metadata.push_back ("classifytype");
+  metadata.push_back ("archivedir");
+  
+  if (!arg_d.empty()) {
+    // we're at document level
+    
+    // get metadata for this document and it's parents
+    if (get_info (arg_d, collection, metadata, true, collectproto, response, logout)) {
+      disp.setmacro ("header", "document", "_textheader_");
+
+      disp.setmacro ("thisOID", "Global", response.docInfo[0].metadata["archivedir"].values[0]);
+
+      text_t &classifytype = response.docInfo[0].metadata["classifytype"].values[0];
+      if (classifytype.empty()) classifytype = "Book"; // defaults to Book
+
+      // set arrow macros if required
+      if (((classifytype == "Book") && (formatinfo.DocumentArrowsTop || formatinfo.DocumentArrowsBottom)) ||
+	  ((classifytype == "Hierarchy") && formatinfo.DocumentArrowsBottom))
+	set_arrow_macros (arg_d, classifytype, formatinfo.DocumentTopPages, 
+			  disp, collectproto, collection, logout);
+      
+      if (args["u"] != "1")
+	set_java_macros (args, disp);
+
+    }
+  } else {
+    if (!arg_cl.empty()) {
+	
+      // get metadata for top level classification
+      text_t classtop;
+      get_top (arg_cl, classtop);
+      if (get_info (classtop, collection, metadata, false, collectproto, response, logout)) {
+	  
+	text_t &title = response.docInfo[0].metadata["Title"].values[0];
+	text_t &classifytype = response.docInfo[0].metadata["classifytype"].values[0];
+
+	disp.setmacro ("pagetitle", "document", "_text" + title + "page_");
+	disp.setmacro ("imagethispage", "document", "_icon" + title + "page_");
+
+	// now get the metadata for each child of top level
+	// so we can generate the _classificationlinks_ and arrow macros
+	// (if they're required by the current classification type)
+	
+	if ((classifytype == "AZList") || (classifytype == "DateList"))
+	  get_classificationlinks (arg_cl, collection, collectproto, disp, logout);
+      
+      }
+    }
+  }
+}
+
+*/
+
+void cstrdocaction::output_document (const text_t &OID, cgiargsclass &args, 
+				     recptproto *collectproto, displayclass &disp, 
+				     outconvertclass &outconvert, ostream &textout, 
+				     ostream &logout) {
+  FilterResponse_t inforesponse;
+  text_tset metadata;
+  bool getParents = false;
+  text_t &collection = args["c"];
+  text_t &arg_gg = args["gg"];
+
+  if (arg_gg == "abstract") {
+    metadata.insert ("Description");
+    text_t top;
+    get_top (OID, top);
+    if (get_info (top, collection, metadata, getParents, collectproto, inforesponse, logout)) {
+      text_t &description = inforesponse.docInfo[0].metadata["Description"].values[0];
+
+      if (!description.empty())
+	textout << outconvert << disp << "<p>\n" << description << "\n";
+      else
+	textout << outconvert << disp << "_textnoabstract_";
+    }
+  } else if (arg_gg == "figures") {
+    metadata.insert ("figures");
+    text_t top;
+    get_top (OID, top);
+    if (get_info (top, collection, metadata, false, collectproto, inforesponse, logout)) {
+      text_t &figures = inforesponse.docInfo[0].metadata["figures"].values[0];
+
+      if (!figures.empty()) {
+	text_tarray figure_array;
+	splitchar (figures.begin(), figures.end(), ',', figure_array);
+	text_tarray::const_iterator this_figure = figure_array.begin();
+	text_tarray::const_iterator end_figure = figure_array.end();
+	while (this_figure != end_figure) {
+	  textout << outconvert << disp 
+		  << "<p><center><img border=1 src=\"_httpprefix_/collect/cstr/index/assoc/_thisOID_/" 
+		  << *this_figure << "\"></center>\n";
+	  this_figure ++;
+	}
+      } else {
+	textout << outconvert << disp << "_textnofigures_";
+      }
+    }
+  } else if (arg_gg == "facsimiles") {
+    metadata.insert ("facsimiles");
+    text_t top;
+    get_top (OID, top);
+    if (get_info (top, collection, metadata, false, collectproto, inforesponse, logout)) {
+      text_t &facsimiles = inforesponse.docInfo[0].metadata["facsimiles"].values[0];
+      
+      if (!facsimiles.empty()) {
+	text_tarray facs_array;
+	splitchar (facsimiles.begin(), facsimiles.end(), ',', facs_array);
+	text_tarray::const_iterator this_facs = facs_array.begin();
+	text_tarray::const_iterator end_facs = facs_array.end();
+	while (this_facs != end_facs) {
+	  textout << outconvert << disp 
+		    << "<p><center><img border=1 src=\"_httpprefix_/collect/cstr/index/assoc/_thisOID_/" 
+		  << *this_facs << "\"></center>\n";
+	  this_facs ++;
+	}
+      } else {
+	textout << outconvert << disp << "_textnofacsimiles_";
+      }
+    }      
+    
+  } else {
+
+    FilterResponse_t queryresponse;
+    bool highlight = false;
+    int wanttext = 0;
+    int arg_gt = args.getintarg("gt");
+
+    // if we have a query string and highlighting is turned on we need
+    // to redo the query to get the terms for highlighting
+    if (!args["q"].empty() && args.getintarg("hl")) {
+      FilterRequest_t request;
+      request.filterResultOptions = FRmatchTerms;
+      comerror_t err;
+      text_t formattedstring = args["q"];
+      format_querystring(formattedstring, args.getintarg("b"));
+      set_queryfilter_options (request, formattedstring, args);
+      collectproto->filter (args["c"], request, queryresponse, err, logout);
+      if (err != noError) {
+	outconvertclass text_t2ascii;
+	logout << text_t2ascii
+	       << "documentaction::output_document: call to QueryFilter failed "
+	       << "for " << args["c"] << " collection (" << get_comerror_string (err) << ")\n";
+	highlight = false;
+      } else {
+	highlight = true;
+      }   
+
+    }
+    
+    format_t *formatlistptr = new format_t();
+    parse_formatstring (formatinfo.DocumentText, formatlistptr, metadata, getParents);
+    
+    metadata.insert ("hastxt");
+    metadata.insert ("haschildren");
+    
+    if (formatinfo.DocumentText == "[Text]")
+      wanttext = 1;
+    else {
+      char *docformat = formatinfo.DocumentText.getcstr();
+      if (strstr (docformat, "[Text]") != NULL)
+	wanttext = 2;
+      delete docformat;
+    }
+    
+    if (get_info (OID, collection, metadata, getParents, collectproto, inforesponse, logout)) {
+      int hastxt = inforesponse.docInfo[0].metadata["hastxt"].values[0].getint();
+      int haschildren = inforesponse.docInfo[0].metadata["haschildren"].values[0].getint();
+      
+      if (arg_gt == 0) {
+	output_text (inforesponse.docInfo[0], formatlistptr, queryresponse.termInfo, 
+		     OID, highlight, hastxt, wanttext, collection, collectproto, 
+		     disp, outconvert, textout, logout);
+	
+	
+      } else {
+	
+	ResultDocInfo_t thisdocinfo = inforesponse.docInfo[0];
+	
+	// text is to be expanded
+	text_t exOID = OID;
+	if (haschildren != 1) exOID = get_parent (OID);
+	if (exOID.empty()) exOID = OID;
+	
+	// if we're not in a document (i.e. we're in a top level classification)
+	// we need to pass the "classify" string to get_contents so that it 
+	// doesn't recurse all the way through each document in the classification
+	bool is_classify = false;
+	if (args["d"].empty()) is_classify = true;
+
+	get_contents (exOID, is_classify, metadata, collection, 
+		      collectproto, inforesponse, logout);
+	
+	ResultDocInfo_tarray::iterator sechere = inforesponse.docInfo.begin();
+	ResultDocInfo_tarray::iterator secend = inforesponse.docInfo.end();
+	
+	if (arg_gt == 1) {
+	  // check if there are more than 10 sections containing text to be expanded - 
+	  // if there are output warning message - this isn't a great way to do this
+	  // since the sections may be very large or very small - one day I'll fix it 
+	  // -- Stefan.
+	  int seccount = 0;
+	  while (sechere != secend) {
+	    int shastxt = (*sechere).metadata["hastxt"].values[0].getint();
+	    if (shastxt == 1) seccount ++;
+	    if (seccount > 10) break;
+	    sechere ++;
+	  }
+	  if (seccount > 10) {
+	    // more than 10 sections so output warning message and text 
+	    // for current section only
+	    textout << outconvert << disp << "_document:textltwarning_";
+
+	    output_text (thisdocinfo, formatlistptr, queryresponse.termInfo, 
+			 OID, highlight, hastxt, wanttext, collection, 
+			 collectproto, disp, outconvert, textout, logout);
+	  
+	  }
+	  else arg_gt = 2;
+	}
+	
+	if (arg_gt == 2) {
+	  // get the text for each section
+	  sechere = inforesponse.docInfo.begin();
+	  int count = 0;
+	  while (sechere != secend) {
+	    textout << outconvert << disp << "\n<p><a name=" << count << "></a>\n";
+
+	    int shastxt = (*sechere).metadata["hastxt"].values[0].getint();
+
+	    output_text (*sechere, formatlistptr, queryresponse.termInfo, 
+			 (*sechere).OID, highlight, shastxt, wanttext, collection, 
+			 collectproto, disp, outconvert, textout, logout);
+	    count ++;
+	    sechere ++;
+	  }
+	}
+      }
+    }
+    delete formatlistptr;
+  }
+}
+
+
+bool cstrdocaction::do_action (cgiargsclass &args, recptprotolistclass *protos, 
+				browsermapclass *browsers, displayclass &disp, 
+				outconvertclass &outconvert, ostream &textout, 
+				ostream &logout) {
+
+
+  // must have a valid collection server
+  recptproto *collectproto = protos->getrecptproto (args["c"], logout);
+  if (collectproto == NULL) {
+    logout << "cstrdocaction::do_action called with NULL collectproto\n";
+    textout << outconvert << disp << "_document:header_\n" 
+	    << "Error: Attempt to get document without setting collection\n"
+	    << "_document:footer_\n";
+  } else {  
+    
+    text_t OID = args["d"];
+    if (OID.empty()) OID = args["cl"];
+    if (OID.empty()) {
+      textout << outconvert << disp << "Document contains no data_document:footer_\n";
+      return true;
+    }
+
+    textout << outconvert << disp << "_document:header_\n"
+	    << "_document:content_\n";
+
+    if (args["d"].empty()) {
+      output_toc (args, browsers, formatinfo, collectproto, 
+		  disp, outconvert, textout, logout);
+    } else {
+      output_cstr_toc (args, browsers, formatinfo, collectproto, 
+		       disp, outconvert, textout, logout);
+
+      textout << "<p>\n";
+      output_document (OID, args, collectproto, disp, outconvert, textout, logout);
+    }
+
+    textout << outconvert << disp << "_document:footer_\n";
+  }
+  return true;
+}
+
+
+
+
+
+
+
+
+
+
+
+
Index: collections/trunk/cstr/src/recpt/cstrdocaction.h
===================================================================
--- collections/trunk/cstr/src/recpt/cstrdocaction.h	(revision 14141)
+++ collections/trunk/cstr/src/recpt/cstrdocaction.h	(revision 14141)
@@ -0,0 +1,72 @@
+/**********************************************************************
+ *
+ * cstrdocaction.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id$
+ *
+ *********************************************************************/
+
+
+#ifndef CSTRDOCACTION_H
+#define CSTRDOCACTION_H
+
+#include "documentaction.h"
+
+class cstrdocaction : public documentaction {
+
+protected:
+
+  void set_java_macros (cgiargsclass &args, displayclass &disp);
+
+  void output_document (const text_t &OID, cgiargsclass &args, 
+			recptproto *collectproto, displayclass &disp, 
+			outconvertclass &outconvert, ostream &textout, 
+			ostream &logout);
+
+
+public:
+  cstrdocaction ();
+  virtual ~cstrdocaction ();
+
+
+  void get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
+			 response_t &response,text_t &response_data, 
+			 ostream &logout);
+  
+  //  void define_internal_macros (const ColInfoResponse_t &collectinfo, displayclass &disp, 
+				   //			       cgiargsclass &args, recptproto *collectproto, 
+				   //			       ostream &logout);
+    
+  bool do_action (cgiargsclass &args, recptprotolistclass *protos, 
+		  browsermapclass *browsers, displayclass &disp, 
+		  outconvertclass &outconvert, ostream &textout, 
+		  ostream &logout);
+  
+};
+
+
+
+#endif
+
+
+
+
Index: collections/trunk/cstr/src/recpt/cstrlibrarymain.cpp
===================================================================
--- collections/trunk/cstr/src/recpt/cstrlibrarymain.cpp	(revision 14141)
+++ collections/trunk/cstr/src/recpt/cstrlibrarymain.cpp	(revision 14141)
@@ -0,0 +1,134 @@
+/**********************************************************************
+ *
+ * cstrlibrarymain.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ *********************************************************************/
+
+#include "receptionist.h"
+#include "cgiwrapper.h"
+#include "nullproto.h"
+#include "collectserver.h"
+#include "filter.h"
+#include "browsefilter.h"
+#include "queryfilter.h"
+#include "infodbclass.h"
+#include "mgsearch.h"
+#include "mggdbmsource.h"
+#include "fileutil.h"
+#include "collectset.h"
+#include <assert.h>
+
+#include "action.h"
+#include "statusaction.h"
+#include "pageaction.h"
+#include "pingaction.h"
+#include "queryaction.h"
+#include "cstrdocaction.h"
+#include "authenaction.h"
+#include "usersaction.h"
+#include "authenaction.h"
+
+#include "browserclass.h"
+#include "vlistbrowserclass.h"
+#include "hlistbrowserclass.h"
+#include "datelistbrowserclass.h"
+#include "invbrowserclass.h"
+#include "cstrpagedbrowserclass.h"
+#include "htmlbrowserclass.h"
+
+#include "recptconfig.h"
+
+int main () {
+  receptionist recpt;
+  nullproto nproto;
+
+  text_t gsdlhome, httpdomain, httpprefix;
+  // get gsdlhome (if we fail the error will be picked up later -- in
+  // cgiwrapper)
+  site_cfg_read (gsdlhome, httpdomain, httpprefix);
+  collectset *cservers = new collectset();
+  cservers->add_collection ("cstr", &recpt, gsdlhome, gsdlhome);
+
+  nproto.set_collectset(cservers);
+
+  // configure the receptionist server list
+  cservers->setReceptionistServers(recpt, gsdlhome);  
+  
+  // add the protocol to the receptionist
+  recpt.add_protocol (&nproto);
+
+  // the list of actions. Note: these actions will become invalid
+  // at the end of this function.
+  statusaction astatusaction;
+  astatusaction.set_receptionist (&recpt);
+  recpt.add_action (&astatusaction);
+
+  pageaction apageaction;
+  apageaction.set_receptionist (&recpt);
+  recpt.add_action (&apageaction);
+
+  pingaction apingaction;
+  recpt.add_action (&apingaction);
+
+  queryaction aqueryaction;
+  aqueryaction.set_receptionist (&recpt);
+  recpt.add_action (&aqueryaction);
+
+  cstrdocaction adocumentaction;
+  adocumentaction.set_receptionist (&recpt);
+  recpt.add_action (&adocumentaction);
+
+  usersaction ausersaction;
+  recpt.add_action (&ausersaction);
+
+  authenaction aauthenaction;
+  aauthenaction.set_receptionist(&recpt);
+  recpt.add_action (&aauthenaction);
+
+  // list of browsers
+  vlistbrowserclass avlistbrowserclass;
+  recpt.add_browser (&avlistbrowserclass);
+  recpt.setdefaultbrowser ("VList");
+
+  hlistbrowserclass ahlistbrowserclass;
+  recpt.add_browser (&ahlistbrowserclass);
+
+  datelistbrowserclass adatelistbrowserclass;
+  recpt.add_browser (&adatelistbrowserclass);
+
+  invbrowserclass ainvbrowserclass;
+  recpt.add_browser (&ainvbrowserclass);
+
+  cstrpagedbrowserclass apagedbrowserclass;
+  recpt.add_browser (&apagedbrowserclass);
+
+  htmlbrowserclass ahtmlbrowserclass;
+  recpt.add_browser (&ahtmlbrowserclass);
+
+  cgiwrapper (recpt, "cstr");
+  return 0;
+}
+
+
+
+
Index: collections/trunk/cstr/src/recpt/cstrpagedbrowserclass.cpp
===================================================================
--- collections/trunk/cstr/src/recpt/cstrpagedbrowserclass.cpp	(revision 14141)
+++ collections/trunk/cstr/src/recpt/cstrpagedbrowserclass.cpp	(revision 14141)
@@ -0,0 +1,115 @@
+/**********************************************************************
+ *
+ * pagedbrowserclass.cpp -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * 
+ *
+ *********************************************************************/
+
+
+#include "cstrpagedbrowserclass.h"
+#include <assert.h>
+#include "OIDtools.h"
+
+cstrpagedbrowserclass::cstrpagedbrowserclass () {
+}
+
+cstrpagedbrowserclass::~cstrpagedbrowserclass () {
+}
+
+
+int cstrpagedbrowserclass::output_section_group (FilterResponse_t &sections, cgiargsclass &args,
+					     const text_t &/*collection*/, int /*colnumber*/, 
+					     format_t * /*formatlistptr*/, bool /*use_table*/, 
+					     text_tset &/*metadata*/, bool &/*getParents*/,
+					     recptproto * /*collectproto*/, displayclass &disp, 
+					     outconvertclass &outconvert, ostream &textout, 
+					     ostream &/*logout*/) {
+
+  text_t &arg_d = args["d"];
+
+  // this browser class only handles document levels
+  if (arg_d.empty()) return 0;
+
+  // dont want page nums and arrows if text is expanded
+  if (!args.getintarg("gt")) {
+    text_t previousOID, previoustitle, nextOID, nexttitle;
+    text_t previousarrow, nextarrow;
+    bool found = false;
+    
+    text_t pagenum;
+    // this should be our list of pages
+    
+    ResultDocInfo_tarray::iterator thissection = sections.docInfo.begin();
+    ResultDocInfo_tarray::iterator endsection = sections.docInfo.end();
+    
+    while (thissection != endsection) {
+      if (arg_d == (*thissection).OID) {
+	found = true;
+	pagenum= "<td><center><b>_document:page_" +
+	  (*thissection).metadata["Title"].values[0] + "\n";
+	if (thissection != sections.docInfo.begin()) {
+	  previousOID = (*(thissection-1)).OID;
+	  previoustitle = (*(thissection-1)).metadata["Title"].values[0];
+	} else 
+	  previousarrow = "_document:parentarrow_";
+	
+	if (thissection != sections.docInfo.end()) {
+	  nextOID = (*(thissection+1)).OID;
+	  nexttitle = (*(thissection+1)).metadata["Title"].values[0];
+	}
+	break;
+      }
+      thissection ++;
+    }
+
+    int numpages = sections.docInfo.size();
+    //pagenum += "_document:textnumpages_(" + text_t(numpages) + ")</center></td>\n";
+    pagenum += "_document:of_" + text_t(numpages) + "</b></center></td>\n";
+    if (!found)
+      nextarrow = "<a href=\"_httpdocument_&cl=" + args["cl"] + "&d=" + sections.docInfo[0].OID + 
+	"\">" + sections.docInfo[0].metadata["Title"].values[0] + "_iconnext_</a>\n";
+    else {
+      if (!previousOID.empty())
+	previousarrow = "<a href=\"_httpdocument_&cl=" + args["cl"] + "&d=" + 
+	  previousOID + "\">_iconprev_</a>\n";
+      if (!nextOID.empty())
+	nextarrow = "<a href=\"_httpdocument_&cl=" + args["cl"] + "&d=" + 
+	  nextOID + "\">_iconnext_</a>\n";
+    }
+  
+    textout << outconvert << disp << "<table><tr valign=top>"
+	    << " <td align=right>" << previousarrow << "</td>\n"
+	    << "<td align=center>" << pagenum << "</td>\n"
+	    << "<td align=left>" << nextarrow << "</td></tr>\n"
+            << "<tr valign=middle>\n"
+            << "<td align=center valign=top colspan=3>_document:gotoform_</td>"
+	    << "</tr></table>\n";
+  }
+  else { // just output goto form
+    textout << outconvert << disp << "<center>_document:gotoform_ </center>";
+  }
+  return 0;
+}
+
+
+
Index: collections/trunk/cstr/src/recpt/cstrpagedbrowserclass.h
===================================================================
--- collections/trunk/cstr/src/recpt/cstrpagedbrowserclass.h	(revision 14141)
+++ collections/trunk/cstr/src/recpt/cstrpagedbrowserclass.h	(revision 14141)
@@ -0,0 +1,57 @@
+
+
+
+/**********************************************************************
+ *
+ * cstrpagedbrowserclass.h -- 
+ * Copyright (C) 1999  The New Zealand Digital Library Project
+ *
+ * A component of the Greenstone digital library software
+ * from the New Zealand Digital Library Project at the
+ * University of Waikato, New Zealand.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * 
+ *
+ *********************************************************************/
+
+
+#ifndef CSTRPAGEDBROWSERCLASS_H
+#define CSTRPAGEDBROWSERCLASS_H
+
+#include "pagedbrowserclass.h"
+
+class cstrpagedbrowserclass : public pagedbrowserclass {
+protected:
+
+public:
+
+  cstrpagedbrowserclass ();
+  virtual ~cstrpagedbrowserclass ();
+
+  int output_section_group (FilterResponse_t &sections, cgiargsclass &args,
+			    const text_t &collection, int colnumber, format_t *formatlistptr, 
+			    bool use_table, text_tset &metadata, bool &getParents,
+			    recptproto *collectproto, displayclass &disp, 
+			    outconvertclass &outconvert, ostream &textout, ostream &logout);
+
+};
+
+#endif
+
+
+
+
