#!/usr/bin/perl
#
#Script:regbibsearch
#
#Author Ivar J. Halvorsen
#4. March 1998
#

$usage1="regbibsearch file string1 [string2 .....]";
$usage2="regbibsearch string1 [string2 .....] < file";
$usage3="regbibsearch file string1 [..] | regbibsearch string2 [...]";
$usage4="regbibsearch -h[elp]";

$usage ="\nUsage:\n\n$usage1 or \n$usage2 or \n$usage3 or\n$usage4\n";

die "$usage\n" if (@ARGV<1);

@helptxt=(
$usage,
"\n",
"REGBIBSEARCH - just another smart perl script\n\n",
"This script can search for strings in records of reg.bib file\n",
"Search strings may be regular expressions (remember quotes).\n",
"All the matching records are written to the standard output,\n",
"and may be piped to another search, or redirected to a file or printer.\n",
"Output records are sorted alphabetically by \@ARTICLE-key\n",
"\n",
"Note that matching on more strings is an OR - operation\n",
"If and AND operation is wanted, this can be done by piping\n",
"ouput for the first string search to input for the second search\n",
"\n",
"Match for string1 OR string2:\n",
"regbibsearch file string1 string2\n",
"\n",
"Match for string1 AND string2:\n",
"regbibsearch file string1 | regbibsearch string2\n",
"\n",
#"Note that exact case is matched. If yoy dont want this,\n",
#"you may use regular expressions. Like this:\n",
#"   \"[Ss]kog\" matches both skog and Skog\n", 
#"\n",
"You should also be careful with special national characters like aa, oe,\n",
"ae, etc. The best way around it is to use the wildcard string: \".*\" like:\n",
"  \"Lundstr.*m\" match Lundstroem, Lundstr\{\\o\} .....\n",
"  \"allg.*wer\" match allgover, Allg\{\\\"o\}wer ....\n",
"\n",
"Another hint is to search for first author by prepending a \\\{ and \n",
"only use the first 3-4 character in his name (this is the syntax in the key).\n",
"\n",
"Examples:\n",
"   regbibsearch ~skoge/reg.bib Skogestad\n",
"   regbibsearch ~skoge/reg.bib Skogestad | regbibsearch Hovd \n",
"   regbibsearch ~skoge/reg.bib \"\\\{hovd\" | lp\n",
"   regbibsearch ~skoge/reg.bib \"199[0-2]\" | regbibsearch Hovd\n",
"   regbibsearch ~skoge/reg.bib Tuning  > \~/tuningarticles.bib\n",
"   regbibsearch ~skoge/reg.bib \"PID?\"\n",
"   regbibsearch ~skoge/reg.bib \tuning | regbibsearch \"PID?\"\n",
"\n",
"See also on the following web site for details on regular expressions in perl:\n",
"ftp://sunsite.uio.no/pub/languages/perl/CPAN/doc/manual/html/pod/perlre.html\n",
"\n",
"Author: Ivar J. Halvorsen\n",
"Date  : 5. March 1998\n",
"\n");

if ($ARGV[0] =~ /^\-h/){
    print @helptxt; 
    exit;
}

if (-p STDIN){
    $file="-";
}
else{
    $file=shift(@ARGV);
}

die "$usage\n" if (@ARGV<1); 

open(BIB,$file) ||die "Cannot open $file\n";

@searchstrings=@ARGV;

#  $file = "/home/skoge/reg.bib";


$top=1;
#Read articles
while(<BIB>){
    next if ($top && !/^\@ARTICLE|^\@[Aa]rticle/);
    $top=0;
    last if (/^\#+\s+Conference proceedings/);
    next unless (/^\@[Aa]\S+\s*\{\s*(\S+.*)\s*$/);
                #relaxed match on ^@Article{xsdask:dd

    $key=$1;
    if(exists $article{$key}){
	$mult{$key}++;
	#print "Warning: Multiple occurance of: $key, changed to ";
	$key.="-$mult{$key}";
	#print "$key\n";
    }

    $article{$key}=$_;
    while(<BIB>){
	$article{$key}.=$_;
	last if (/^\}/);   #Records normally ends with a ^}#
	last if (/^\s*$/); #Also terminate if a blank line is found
    }
}


if (/^\#+\s+Conference proceedings/){
    $proceedings="$&, reports etc. ######";
    }
else {
    $proceedings="";
}

#Read the rest

while(<BIB>){
    next if (/^\#+/);             #skip commentary lines
    next unless (/(\S+.*)\s*$/);  #skip blank lines
    $key=$1;                      #Now the key is just the first line
                                  
    if(exists $other{$key}){
	$mult{$key}++;
	#print "Warning: Multiple occurance of: $key, changed to ";
	$key.="-$mult{$key}";
	#print "$key\n";
    }

    $other{$key}=$_;
    while(<BIB>){
	$other{$key}.=$_;
	last if (/^\s*$/);
    }
}


# Do the search in articles
while (($key,$value) = each %article) {
    foreach $string (@searchstrings){
	if (grep(/$string/i,$value)){
	    #print $value;
	    #print "\n";
	    push(@foundarticles,$key);
	    last;
	}
    }
}


# Do the search in others

while (($key,$value) = each %other) {
    foreach $string (@searchstrings){
	if (grep(/$string/i,$value)){
	    #print $value;
	    #print "\n";
	    push(@foundothers,$key);
	    last;
	}
    }
}


#Then print the results:

foreach $key (sort(@foundarticles)){
    print "$article{$key}\n";
}

print "$proceedings\n\n" if (@foundothers);

foreach $key (sort(@foundothers)){
    print "$other{$key}\n";
}

$noarticles=@foundarticles;
$noothers  =@foundothers;
    
printf("####### Found %d articles and %d other items ###\n",
       $noarticles,$noothers);








