#!/usr/bin/perl 

#2345678901234567890123456789012345678901234567890123456789012345678901234567890
#        10        20        30        40        50        60        70

################################################################################
#12 Mar 2002 : "-a file.name" option (abreviations) is added 
#------------------------------------------------------------------------------
# 4 Dec 2002 : --movepoint option execution is implemented in a separate 
#              function named "ifmovepoint"
################################################################################
# 3 Dec 2001 : Added one more feature. Now you can define TWO references formats
#              One is "ref_format", the other is "ref2_format"
#              First will be applied to \cite{}, the 2nd - to \refcite{}
#              this is usefull because I want to use it as
#                     ....blah blah.$^3$
#              but 
#                     ....blah blah ref 3.
#              So, no move poin is applied to 2nd type REF!!!!
#              If you do not use \refcite substitution, do not forget to include
#              line 
#                   \newcommand{\refcite}{\cite}
#              It is better to have it there anyway!!!
#-------------------------------------------------------------------------------
#
# 4 Oct 2001 : 1. Minor bug is corrected
#              2. Now no points and commas at the beginning of the line
#                 Like in the piece of text
#
#                  Was shown in work
#                  \cite{lab2}. Blah-Blah-Blah
#
#                 if we use --movepoint option we get
#
#                  Was shown in work
#                  .\cite{lab2} Blah-Blah-Blah
#                 
#                 But it should be
#
#                  Was shown in work.\cite{lab2} Blah-Blah-Blah
#
#                 That is exactly what is fixed now.
#                 Although it adds a new bug: if you have
#
#                  Was shown in work
#                  % Blah-Blah-Blah
#                  \cite{lab2}. Blah-Blah-Blah#
#
#                 then one line is LOST!!!!
#------------------------------------------------------------------------------
# 7 Sep 2001 : $optionsREPLACE_POINT is added 
#                      (command line argument --movepoint)
#
#
################################################################################

use strict;
my $BIBLIO_VERSION = '1.21';

##############################################
# important global data structures

                # contains all "labels", found in the tex file in \cite{} command
my @REFS;       # 0 is NOT used at the beginning. After some point it is used!
$REFS[0]='';    # I need '' here because all empty refs will be compared 
                # with this one and thrown out (as if they r already present)!

my @ALLREFS;    # Keeps all data about refs. Is array of hashes
 # for example this piece of the code
 #
 # foreach $item (@ALLREFS)  
 # { 
 #    print ${$item}{"AUTHORL"},"\n"; 
 # };
 #
 # will print all ''AUTHOR'' fields

my %REFSORDERED; # hash, containing the same, what is in the $REFS, 
                 # but  $REFSORDERED[$REFS[$i]] == $i

my %ALLFORMATSTRINGS; #Keeps all format strings in the form:
   #for example $ALLFORMATSTRINGS{'ARTICLE'} is format string for type ARTICLE
my $CITE_FORMAT;my $REF_FORMAT;    # These are for references to articles, etc 
                my $refREF_FORMAT; # (like \cite{...}) and citation at the end of
                                   # your tex-document (\begin{references} ...)
# They are paterns like   ^{%s}  - means just upper script
# Or [%s] will produce something like [1,2,6,7] in \cite 
# and just [1] and [2] and .. in the references (literature) at the end of
# your tex document!

my $ORDERING='';  # must contain key-field, like AUTHORL, or TITLE

#############################################
# reserved names in the references file

my $reservedLABEL='LABEL';
my $reservedTYPE ='TYPE' ;

my $reservedAUTHORL='AUTHORL';
my $reservedAUTHORF='AUTHORF';  #??? po moemu uzhe ne nuzhen!!! ------------???????
my $reservedAUTHOR ='AUTHOR';   #must be in the form '5;' - 5=five authors must be shown.

my $reservedAND_SEPARATOR='|'; #what have to be put before the last author goes after this!!!

my $reservedET_AL='{ \it{et al}}'; #if number of authors more than shown will be added after the last one.


my $reservedDOLLAR = '$';
my $reservedARRAYSEP = '|';
my $reservedCOMMENTSYMBOL = '%';
my $SEPARATOR = "----------\n";

my $reservedHASH_KEY = 'HASH_KEY_'; 
my $reservedEMTY_FIELD_SIGN = '???';  #will be written instead of emty fields
my $reservedNONUMBER = 'NONUMBER';  # if NONUMBER is given in the ref_format or cite_format, then no number will be put in the output.
                                    # for example
                                    # Normally:  [4] Author, F.M. Interesting Articles' Journal
                                    # NONUMBER       Author, ....
#--------------------------------------
# reserved names in the tex file;
my @STARTREFS=  ('begin{references}','begin{thebibliography}');
my @ENDREFS=    ('end{references}',  'end{thebibliography}');

my $CITE = '\\\cite{';
my $CITE0= '\cite{';
my $refCITE = '\\\refcite{';
my $refCITE0= '\refcite{';


my $BIBITEM = '%'."\n".'\bibitem{';

my $reservedBEGINBIBLIO='begin{biblio}';  #options for biblio starts like this
my $reservedENDBIBLIO  ='end{biblio}';    #and end like this!
my $reservedLEFTSTART  ='[';              #TYPE[FORMAT_STRING]
my $reservedRIGHTEND   =']';              #so, example:
  # ARTICLE[$AUTHOR0FL, M; $/  {\bf $YEAR$}, $VOL$] 
my $reservedCITE_FORMAT='cite_format=';  #must be in the form cite_format=^{%s}

my $reservedREF_FORMAT ='ref_format=';   # the same
my $reservedrefREF_FORMAT ='ref2_format=';

my $reservedORDERING   ='ordering=';     #must be in the form ordering=AUTHORL. If no this field is given, then "asis" implied
my $reservedS_STRING   ='%s';
my $reservedS_STRING1  ='\%s';
my $reservedSTANDARD_CITE_FORMAT = "[$reservedS_STRING]";   # default values
my $reservedSTANDARD_REF_FORMAT  = "[$reservedS_STRING]";   # for references formats

my $reservedREFERENCES ='\begin{center} \refname \end{center}' . "\n"; #'\begin{center} {\bf REFERENCES} \end{center}'."\n"
my $reservedSTARTREFS  ='\begin{flushleft}'."\n\n";     #\begin{tabular}{p{0.05\textwidth}p{0.95\textwidth}}'
my $reservedENDREFS    ='\end{flushleft}';              #\end{tabular}'
my $reservedBETWEENREFS="\n";   
my $reservedSEPARATORINCITE=','; # \cite[1,2,3,4] will produce {1$reservedSEPARATORINCITE2$reservedSEPARATORINCITE}
my $reservedMULTISEPARATORINCITE='-';  # \cite{1,2,3,4}  =>  1-4
############################################

my %HASH_REFS;  #CHANGE IT LATER!!!



#$REFS_FILE=  'refs.db';
my @REFS_FILES = ('refers.db');
#my $REFS_FILE='';#  'refers.db';

#-----------------------------------------
#OPTIONS

my $verbosity_level=1;   # 5 is max
my $optionsINSERT_EMPTY_FIELDS_SIGN = 1;
my $optionsKEEP_BIBITEM_AND_CITE    = 1; 
  # if 1 \cite{} will not be substituted and output will be written in the form
  # \bibitem{string}  where string is in the apropriate format (like in format_string)
my $optionsREFS_AS_TEX_LIST =0;  #use list enviroment for references

my $optionsREPLACE_POINT =0; # either Biblio should change "works\cite{}." to "works.\cite" 
my $what_we_call_point = '.,;:'; # all signes condidered to be a POINT-sign.
my $optionsABBREVIATIONS =0; # use abbreviations tex-file 
#-------------------------------------------

my $TEX_NAME ='';#  'probe.tex';
my $OUT_TEX  ='';#  'pprobe.tex';
my $FORMAT_NAME = '';#'macromolecules';#$TEX_NAME;  # file where all rules are!
my $ABBR_NAME = 'abbr.tex';  #abbreviations file

&read_inline_arguments;
&check_for_important_arguments;

if ($verbosity_level > 0)
{   print "\nThis is biblio version $BIBLIO_VERSION\n";
    print 'Author R.Stepanyan <rstepanyan@yahoo.com>',"\n\n";
    print "input tex-file is  <$TEX_NAME>;\n"; 
    print "output file is     <$OUT_TEX>;\n";
    print "formats are in     <$FORMAT_NAME>;\n"; 
    print 'refs databases are <';
    foreach my $qq (@REFS_FILES) {print "$qq "};
    print ">.\n\n";
};
if ($verbosity_level > 1)
{print "cite-tag in your tex-file <$TEX_NAME> assumed to be $CITE \n\n";};


&make_list_of_refs; #makes list of all refs in @REFS

my $i=0;
for($i=0; $i<scalar(@REFS); $i++)
{
    $REFS[$i] = $REFS[$i+1]; 
};
$#REFS--; #now $REFS[0] is also used!!!!

#=========================================================

#TO BE REMOVED - format string will be read from tex-file!
#my $FORMAT_STRING1 ='$AUTHORL$ {\bf $YEAR$}, $VOL$ ' ;
#print "format string = |$FORMAT_STRING1| \n";

#AUTHOR in the format string:
#  'AUTHOR5L, FM; ' means:
# - show max 5 aouthors
# - do it like this
#     'Stepanyan, R.R.; Subbotin, A.; ten Brinke, G.'
#%ALLFORMATSTRINGS= ('ARTICLE' => '$AUTHOR0FL, M; $/  {\bf $YEAR$}, $VOL$ ',
#		    'BOOK'    => 'BOOK $AUTHORL$ {\it $YEAR$}, $VOL$ ' ); #TO BE CHANGED should be read from file!!!

&read_formats_and_speak_to_me;  #???????????????????
# OK, we now have 
# 1.  %ALLFORMATSTRINGS
# 2   $CITE_FORMAT  and  $REF_FORMAT;




$i=0;
my $item;
if($verbosity_level > 3)
{
foreach $item (@REFS)  #
 {print "cite N$i is $item \n"; $i++ 
 };
};
if($verbosity_level > 4)
{print "make_list_of_refs from <$TEX_NAME> done...\n\n";}

my $REFS_FILE;
foreach  $REFS_FILE (@REFS_FILES)
{ #print $REFS_FILE, "-------\n";
  &read_ref_datafile($REFS_FILE);  # all data will be stored in @ALLREFS - array of hashes
  if($verbosity_level > 4)
    {print "read_ref_datafile <$REFS_FILE> done...\n";}
};
if($verbosity_level > 4){print "\n";}

#this shows how to access @ALLREFS
#foreach $item (@ALLREFS) 
#{ 
#   print ${$item}{"LABEL"},"-->",${$item}{"VOL"},"\n"; 
#};

if($verbosity_level > 0)
{&complain_about_nonexisting_refs;}

&order_this_list;
if($verbosity_level > 4)
    {print "ordering of refs is done...\n";}


open(OUTTEX, "> $OUT_TEX");    
open(TEX,"$TEX_NAME");

my $do_insert=0; # if 0 - nothing has been done
                 # if 1 - process is going on
                 # if 2 - it is done
                 # if 3 - \end{references} is over
my $line;
while(<TEX>)
{   $line = $_;  

    chomp($line); #added 4 oct
                    
    foreach my $s (@STARTREFS) 
      {
        if($s eq substr($line,1,scalar(split(//,$s)))) 
           {&insert_abbreviations_of_journals; $do_insert = 1;}
      };
    if(($do_insert==0)||($do_insert==3)||($optionsKEEP_BIBITEM_AND_CITE==1))
    { # added  11 March 20002
      if($optionsKEEP_BIBITEM_AND_CITE)
      { if($optionsREPLACE_POINT)
        {
           (my @qguess0) =( $line =~ /$CITE([^}]*)/gi );  
                          #now there r all xxx from \cite{xxx} in this array
           my @qguess=trim(@qguess0); #???????????????  $dst =~ s/this/that/;
           for(my $i=0; $i<scalar(@qguess); $i++)
           { 
               my $this = "$CITE$qguess[$i]}";
               $line = ifmovepoint($this,$line)
           }
        };
        # end 11 March 20002
        print OUTTEX "\n$line"
       }
      else 
       {&find_there_cites_and_substitute_them($line)}
    };                                
    if(($do_insert==2)&&($optionsKEEP_BIBITEM_AND_CITE!=1))
    {
	foreach my $s (@ENDREFS) {if($s eq substr($line,1,scalar(split(//,$s)))) {$do_insert = 3;}};
    };
    next if $do_insert > 1;
    next if $line =~ /^\s*$/; # skip blank lines
    next if (substr(trim($line),0,1) eq $reservedCOMMENTSYMBOL);  # we r not interested in comments
    $line = trim($line);
    # foreach my $s (@STARTREFS) {if($s eq substr($line,1,scalar(split(//,$s)))) {$do_insert = 1;}};
    next if $do_insert ne 1;
      if($optionsKEEP_BIBITEM_AND_CITE) 
        { #\begi{references} is already written
          &print_all_references_into_tex_in_bibitem_format; $do_insert = 2; 
        }
      else    
      { if($optionsREFS_AS_TEX_LIST!=1){&print_all_references_into_tex; $do_insert = 2;}
        else{&print_all_references_into_tex_as_list; $do_insert = 2;}
      };
    
};  
close(OUTTEX);
close(TEX);

if ($verbosity_level > 0) {  print "\nFinished!\n"}
exit(0);



###############################################
#*********************************************
##############################################
#********************************************
###############################################
#===========================



#makes list of all cites and place them into @REFS
#order is according to their place in the tex-file
sub make_list_of_refs 
{
my $guess; my @multiguess; my $last; my (@qguess,@qguess2);
open(TEX, $TEX_NAME)|| die "Could not open $TEX_NAME: $!";
  while (<TEX>) {   # read a line from file TEX into $_
    $last = $_;
    #next if (substr($last,0,1) eq "$reservedCOMMENTSYMBOL"); 
    if ($last =~ m/$reservedCOMMENTSYMBOL/)
    {  if($last =~ m/\\$reservedCOMMENTSYMBOL/)
       {   my $new_last='';#split(//,$last);
          # my $last1='';
	  # print $last," <-- is \n";
          # for($i=0;$i<scalar(@new_last);$i++)
          # {
          #    if()
	  # };
           my @spl=split(/\\$reservedCOMMENTSYMBOL/,$last);
           for($i=0;$i<scalar(@spl);$i++)
           {
	       if(substr($spl[$i], -1) eq "\\") {$new_last = $new_last ."\\" ;last};
               if($spl[$i] =~ m/$reservedCOMMENTSYMBOL/)
               { my ($temp)=split(/$reservedCOMMENTSYMBOL/,$spl[$i]);
                 $new_last = $new_last . $temp;
                 last;
               }
               else
               {$new_last = $new_last . $spl[$i];}
	   };
           $last = $new_last;
       }
       else
       {
          ($last)= split( /$reservedCOMMENTSYMBOL/,$last);
       };
       #Now we should look, might be it was "\%" but not "%" 

    };
    next if (trim($last) eq '' );   
 
#    ($guess) =( $last =~ /$CITE([^}]*)/ ); 
     (@qguess) =( $last =~ /$CITE([^}]*)/gi );
     (@qguess2) =( $last =~ /$refCITE([^}]*)/gi );
     $guess="";
     my $nn=scalar(@qguess);
     for($i=0; $i<$nn; $i++)
        {$guess=$guess.','.$qguess[$i]}; 
     my $nn=scalar(@qguess2);
     for($i=0; $i<$nn; $i++)
        {$guess=$guess.','.$qguess2[$i]};     

    $guess=trim($guess);  # remove SPACE from the beginning and end
    if($guess ne '')
    {#print "\n this is guess:  $guess \n";
   
     @multiguess = split(/,/ , $guess); # if this is \cite{1,2,3,4,..}
     @multiguess = trim(@multiguess);

     my $nmulti=scalar(@multiguess);
          
     for($i=0; $i<$nmulti; $i++)
      { #print $i,"=",$multiguess[$i]," ";
        my $notfound=1;
        foreach $item (@REFS)
        { if($item eq $multiguess[$i]){$notfound =0; last }
        };
     
        if($notfound) {$nn=scalar(@REFS); $REFS[$nn] = $multiguess[$i];}
      };     
    }    
  };
     
  
close(TEX);


};

#--------------------------------------------------------

sub read_ref_datafile 
#________________________________________________ 
#reads references file. Data stored in @ALLREFS
#structure of the refs-file:
#LABEL=3dFlex
#TYPE=article
#AUTHORL=subbotin
#TITLE={Microphase separation within comb-like copolymer with attractive  side-chains: computer simulations1.}
#JOURNAL=   Macromol. Theory and Simul1.
#----------<10pieces>
#
#At the end should be Enter, so better to put EOF after it in the
#next line
#
{ my $current_ref_number=0; my $line;
  my @fields; my %CURRENT_RECORD;

  my $it_is_label=1; my $save_current_field=0;
 
  my $item;
  my $REFS_FILE = @_[0];
  
  open(RF, $REFS_FILE)|| die "Could not open $REFS_FILE: $!";
  while($line = <RF>)
  {   next if $line =~ /^\s*$/; # skip blank lines
      next if (substr(trim($line),0,1) eq $reservedCOMMENTSYMBOL);
      if($line ne $SEPARATOR)
      {
        $line=trim($line);
        @fields = split(/=/, $line);

        @fields = trim(@fields);
        
        if($fields[0] eq $reservedLABEL)
        {
	    foreach $item (@REFS) 
            { if($item eq $fields[1]) #this label is in REFS
               { $save_current_field = 1 } 
            }
        };
        
        if($save_current_field)
	{ if($fields[0] eq $reservedLABEL){$CURRENT_RECORD{$fields[0]} = $fields[1]; }
	  else
	  {
	      if($CURRENT_RECORD{$fields[0]} ne '')
	      {
		  $fields[1]=trim($fields[1]);
		  $CURRENT_RECORD{$fields[0]}="$CURRENT_RECORD{$fields[0]}$reservedARRAYSEP$fields[1]" ;	      
	      }
	      else
	      {$CURRENT_RECORD{$fields[0]} = trim($fields[1]); }
	  };    
              #MUST change it to read fields with many '=' in the body text!!!
          #print "$fields[0] == $CURRENT_RECORD{$fields[0]}\n";
        }
      }
      else
      {
	if($save_current_field)
	{  %{$ALLREFS[$current_ref_number]} = %CURRENT_RECORD;  
	# Now erase everything from the hash!!!
	   my @allkeysfromhash = keys %CURRENT_RECORD;
           foreach $item (@allkeysfromhash){delete($CURRENT_RECORD{$item})};
	   
           $current_ref_number++; #print "-------\n";
        };
        $save_current_field = 0;
      }; 
  };
  close(RF);
};

#----------------------------------------------------------

sub complain_about_nonexisting_refs
#check that all @REFS have counterpart in @ALLREFS
{my $item=''; my $item1=''; my $good_label;
  
  foreach $item (@REFS)
  { $good_label=0;
    foreach $item1 (@ALLREFS)
     {if($item eq ${$item1}{"$reservedLABEL"}) {$good_label=1; next;}}
    if($good_label == 0)
    { print STDERR "  WARNING!  Cite-label <$item> has not been resolved! \n";
    } 
  };
  print STDERR "\n";
}

#---------------------------------------------------
sub read_formats_and_speak_to_me
#calls read_format_string  and also produces output about results
{
&read_format_strings;
if($verbosity_level > 3)
{print "\nread_format_strings from <$FORMAT_NAME> done...\n\n";
 printf("%16s | %s\n","TYPE","FORMAT STRING");
 printf("%15s--+-%s\n","---------------","---------------------------------------------------");
 foreach my $key (keys %ALLFORMATSTRINGS)
   { printf("%16s | %s\n",$key,$ALLFORMATSTRINGS{$key})};
 for(my $i=0;$i<70;$i++){print "-";};print "\n";
};
if($CITE_FORMAT eq '')
{ print STDERR "Citation format not found or wrong in <$FORMAT_NAME>. Assuming default!\n";
  $CITE_FORMAT = $reservedSTANDARD_CITE_FORMAT
};
if(uc($CITE_FORMAT) eq $reservedNONUMBER){$CITE_FORMAT='';}; #????????
if($REF_FORMAT  eq '')
{ print STDERR "Citation reference format not found or wrong in <$FORMAT_NAME>. Assuming default!\n";
  $REF_FORMAT  = $reservedSTANDARD_REF_FORMAT
};

#print "$CITE_FORMAT  $REF_FORMAT \n";
if($verbosity_level > 0)
 {   print "\n!!! Citation format:$CITE_FORMAT. \n    Reference format=$REF_FORMAT. Second reference format=$refREF_FORMAT.\n    Ordering:";
     if($ORDERING eq ''){print "as is\n\n"}else {print " key field is <$ORDERING>\n\n"} 
 };

}

#----------------------------
sub read_format_strings
# this function reads formats for references from file $FORMAT_NAME
# this can be just header in the decument (tex-file) or separate file!
{my $line='';
 my $start_interpreting=0; # 0 - not started yet
                           # 1 - interpreting
  
 my @justarray; 

    if($verbosity_level > 3){print "Format strings are in <$FORMAT_NAME>\n\n"}

    open(FRM, "$FORMAT_NAME") || die "Could not open $FORMAT_NAME: $!";
    while(<FRM>)
    {   my $hash_key=''; my $hash_value='';
	$line = $_; #print $line;
        $line = trim($line);
        next if $line =~ /^\s*$/; # skip blank lines
        next if (substr(trim($line),0,1) ne $reservedCOMMENTSYMBOL);
                 #skip lines, starting NOT from %
        next if (substr(trim($line),0,2) eq "$reservedCOMMENTSYMBOL$reservedCOMMENTSYMBOL");
        $line = substr(trim($line),1);
        $line=trim($line);
        next if $line =~ /^\s*$/;
        if($line eq $reservedBEGINBIBLIO){$start_interpreting=1;next;};
        if($line eq $reservedENDBIBLIO){ close(FRM); return;};

           
        if(not $start_interpreting){next;};

          #OK, now no shit in this line!  
        if($verbosity_level > 4){print $line," is read from <$FORMAT_NAME>\n";};
        @justarray=split(//,$line);

        #try to find if this is "cite_format" or "ref_format"
        my $format='';
        ($format) = ($line =~ /$reservedCITE_FORMAT([^,\n]*)/); 
        if($format ne '')
	   {if(($format =~ m/$reservedS_STRING1/)||($format =~/$reservedNONUMBER/))  
              { $CITE_FORMAT = $format; 
                if($verbosity_level > 4){print "Citation format=$format\n\n";}
                next;
	      }
	    else
	     {print STDERR "Unknown citation format \"$format\". Assuming standard=",
                            "$reservedSTANDARD_CITE_FORMAT\n";
              $CITE_FORMAT = $reservedSTANDARD_CITE_FORMAT ; next;
             }
           }  ;
         # now try to find "ref_format" 
        ($format) = ($line =~ /$reservedREF_FORMAT([^,\n]*)/); 
        if($format ne '')
	   {if($format =~ m/$reservedS_STRING1/)    
              { $REF_FORMAT = $format; 
                if($verbosity_level > 4){print "Citation reference format=$format\n\n";};
                next;
	      }
	    else
	     {print STDERR "Unknown reference format \"$format\". Assuming standard: ",
                            "$reservedSTANDARD_REF_FORMAT\n";
              $REF_FORMAT = $reservedSTANDARD_REF_FORMAT ; next;
             }
           }  
        ($format) = ($line =~ /$reservedrefREF_FORMAT([^,\n]*)/);       
        if($format ne '')
	   {if($format =~ m/$reservedS_STRING1/)    
              { $refREF_FORMAT = $format; 
                if($verbosity_level > 4){print "Citation reference 2nd format=$format\n\n";};
                next;
	      }
	    else
	     {print STDERR "Unknown 2nd reference format \"$format\". Assuming standard: ",
                            "$reservedSTANDARD_REF_FORMAT\n";
              $refREF_FORMAT = $reservedSTANDARD_REF_FORMAT ; next;
             }
           }        

        ($format) = ($line =~ /$reservedORDERING([^,\n]*)/); 
	if($format ne '') 
	   {$ORDERING = trim($format); 
	    if($verbosity_level > 4){print "Key field for refs ordering=$ORDERING\n\n";}; 
	    next;
	   } ;
	
	my $this_is_key=1;
	
        my $narray=scalar(@justarray);
        for(my $i=0;$i< $narray-1; $i++)
        { 
	    if(($this_is_key)&&($justarray[$i] eq $reservedLEFTSTART))
                {$this_is_key = 0; next;};
          if($this_is_key)
            {$hash_key ="$hash_key$justarray[$i]";} 
	  else
            {$hash_value = "$hash_value$justarray[$i]"}
     	};
        if($justarray[$narray-1] ne $reservedRIGHTEND)
          {
            print STDERR "Format string \"$line\" must end with \"$reservedRIGHTEND\"!\n";
            print STDERR "This is fatal error. Exiting...";
            exit(1);
          };
        $hash_key=trim($hash_key);
        #now analize $hash_key. It must be puur symbolic!
        unless($hash_key=~ /^[A-Za-z0-9]+$/)
          {print STDERR "Key field \"$hash_key\" in  \"$line\" must include only A-Z,a-z,0-9\n";
           print STDERR "This is fatal error. Exiting...";
           exit(1);
          };
      
        my $hash_key1=uc($hash_key);

        if (($hash_key1 ne $hash_key)&&($verbosity_level>2))
           {print " WARNING!!! Key field\n   \"$hash_key\" in \"$line\"\n converted to uppercase!!!\n"};
        $ALLFORMATSTRINGS{$hash_key1} = $hash_value;
        
    };
    close(FRM);


};

#------------------------------------------------------------

#reads REFS_FILE and finds there text for references 
#according to labels in @REFS
#All Refs are put into hash  %HASH_REFS where index is $REFS (label)
sub prepare_all_refs
{
    my $HASH_CURRENT_ITEM;

 open(REFF,$REFS_FILE)|| die "Could not open $REFS_FILE: $!";
 my $this_is_label=1; my $label; my $last ; my $refitem;
 my $HAS_CURRENT_ITEM;
 while(<REFF>)
 { 
   $last = $_; 
   if($this_is_label)
    { $label=$last;chomp($label);$label=trim($label);
      foreach $refitem (@REFS)
      {if($label eq $refitem) 
        {$HASH_CURRENT_ITEM = $label;
         print "found $refitem in $REFS_FILE\n"
        } 
      }
      $this_is_label=0;
    }   
   elsif($last eq $SEPARATOR){$this_is_label=1; 
                              print  $HASH_REFS{$HASH_CURRENT_ITEM},"\n";}
   else
    {
      $HASH_REFS{$HASH_CURRENT_ITEM}=$HASH_REFS{$HASH_CURRENT_ITEM} . $last;
      #print  $HASH_REFS{$refitem},"\n";
    } 
    
 };
 close(REFF);
};
#---------------------------------------------------------- 

sub print_all_references_into_tex_in_bibitem_format
{ my $item1; 
  print OUTTEX "\n",'%Generated by biblio',"\n";
  for(my $i=0;$i<scalar(@REFS);$i++)
  { $item  = @REFS[$i];
    foreach $item1 (@ALLREFS)  #loop 1
     {if($item eq ${$item1}{"$reservedLABEL"}) 
       { my $thetype=uc(${$item1}{"$reservedTYPE"}); # IN THE UPPER CASE!
	 if($ALLFORMATSTRINGS{"$thetype"} eq '') 
	 {   print STDERR "No format string for TYPE <$thetype>. Skipping record <$item>!\n";
	     last;
	 };
     
         print OUTTEX $BIBITEM,$item,'}',"\n",'{'; #,$CITE_FORMAT;
	 
	 #print $thetype,"-->",$ALLFORMATSTRINGS{"$thetype"}, "\n";
            
	 &formated_output($ALLFORMATSTRINGS{"$thetype"},%{$item1}); #CHANGE $FORMAT_STRING1 HERE!!!
	 print OUTTEX '}',"\n";
	 #next;
       
	 last; #this is last for loop 1
       }
     };
     
  }; 
  print OUTTEX '%',"\n",'%End of Generated by biblio',"\n";  
  
}
#-----------------------------------------------------------
sub print_all_references_into_tex    #OUTTEX must be opened!
{
my $item1; my $st;

  print OUTTEX "\n$reservedREFERENCES$reservedSTARTREFS";
  
  my $counter=1;
  
  my $found_it=0;
  
  for(my $i=0;$i<scalar(@REFS);$i++)
  { $item  = @REFS[$i];
    $found_it=0;  
      
    foreach $item1 (@ALLREFS)
     {if($item eq ${$item1}{"$reservedLABEL"}) 
       { my $thetype=uc(${$item1}{"$reservedTYPE"}); # IN THE UPPER CASE!
	 if($ALLFORMATSTRINGS{"$thetype"} eq '') 
	 {   print STDERR "No format string for TYPE <$thetype>. Skipping record <$item>!\n";
	     $st = sprintf("$CITE_FORMAT",$counter);
	     print OUTTEX "$st ";#,$CITE_FORMAT;
	     $counter++;
	     print OUTTEX "No format string for TYPE <$thetype>. Skipping record <$item>!";
	     print OUTTEX "\n$reservedBETWEENREFS";
	     $found_it = 1;
	     last;
	 };
	 $st = sprintf("$CITE_FORMAT",$counter);
	 print OUTTEX "$st ";#,$CITE_FORMAT;
	 $counter++;
	 #print $thetype,"-->",$ALLFORMATSTRINGS{"$thetype"}, "\n";	 
         &formated_output($ALLFORMATSTRINGS{"$thetype"},%{$item1}); #CHANGE $FORMAT_STRING1 HERE!!!
         print OUTTEX "\n$reservedBETWEENREFS";
	 $found_it=1;
	 last;
       }
     }
    unless($found_it)
    {
      $st = sprintf("$CITE_FORMAT",$counter);
      print OUTTEX "$st ";#,$CITE_FORMAT;
      $counter++;
      print OUTTEX "Record <$item> was not found in the references dbases";
      print OUTTEX "\n$reservedBETWEENREFS";
    }
  };
  print OUTTEX "$reservedENDREFS\n"; 
};

#------------------------------------------------------------
sub print_all_references_into_tex_as_list
{
  my $item1; my $st;
  
  print OUTTEX  "\n$reservedREFERENCES";
  
  print OUTTEX  '\newcounter{bibliocounterrr}',"\n";
  print OUTTEX  '\begin{list}';
  
  $st = sprintf("$CITE_FORMAT",'\arabic{bibliocounterrr}');
  print OUTTEX '{',"$st",'}',"\n";#,$CITE_FORMAT;
  print OUTTEX '  {\usecounter{bibliocounterrr}',"\n";
  print OUTTEX '  \setlength{\labelwidth}{1cm}\setlength{\leftmargin}{1cm}',"\n";
  print OUTTEX '  \setlength{\labelsep}{0.5cm}\setlength{\rightmargin}{0cm}',"\n";
  print OUTTEX '  \setlength{\parsep}{0.5ex plus0.2ex minus0.1ex}';
  print OUTTEX '  \setlength{\itemsep}{1ex plus0.2ex}',"\n"; 
  print OUTTEX '}',"\n";
  
  
  
  
  my $found_it=0;
  
  for(my $i=0;$i<scalar(@REFS);$i++)
  { $item  = @REFS[$i];
    $found_it=0;  
      
    foreach $item1 (@ALLREFS)
     {if($item eq ${$item1}{"$reservedLABEL"}) 
       { my $thetype=uc(${$item1}{"$reservedTYPE"}); # IN THE UPPER CASE!
	 if($ALLFORMATSTRINGS{"$thetype"} eq '') 
	 {   print STDERR "No format string for TYPE <$thetype>. Skipping record <$item>!\n";
	 
	     print OUTTEX '\item ';
	     
	     print OUTTEX "No format string for TYPE <$thetype>. Skipping record <$item>!";
	     print OUTTEX "\n$reservedBETWEENREFS";
	     $found_it = 1;
	     last;
	 };
	 
	 print OUTTEX '\item ';#,$CITE_FORMAT;
       
	 #print $thetype,"-->",$ALLFORMATSTRINGS{"$thetype"}, "\n";	 
         &formated_output($ALLFORMATSTRINGS{"$thetype"},%{$item1}); #CHANGE $FORMAT_STRING1 HERE!!!
         print OUTTEX "\n$reservedBETWEENREFS";
	 $found_it=1;
	 last;
       }
     }
    unless($found_it)
    {
      
      print OUTTEX '\item ';#,$CITE_FORMAT;
    
      print OUTTEX "Record <$item> was not found in the references dbases";
      print OUTTEX "\n$reservedBETWEENREFS";
    }
  };
  print OUTTEX '\end{list}',"\n";   
    
};    
#------------------------------------------------------------

sub formated_output
# takes format string in the form
# $FORMAT_STRING ='$AUTHOR5F L;$ {\bf $YEAR$}, $VOL$ - $NUMBER$' ; 
# and hash
# of the type
# my %HASH_REFS= ('AUTHOR' => 'Stepanyan',
#                 'YEAR'   => '2000',
#                 'VOL'    => '12',
#                 'RT'     => 'qq');  
# of course fields in hash can be any.
# Then makes output of the hash into stdout
# according to the format string.
# File with file handle OUTTEX must be opened for writing!!!!
{
my @in_arguments = @_;  #take all arguments of this function

my $FORMAT_STRING=$in_arguments[0]; # the first MUST be the format string

my %HASH_REFS;  #all the rest of arguments 
                #must be put into this hash

my $i; #next lines make hash from array
for($i=1;$i<scalar(@in_arguments)-1;$i=$i+2)
{ $HASH_REFS{$in_arguments[$i]} = $in_arguments[$i+1]
};


my @format_char_array; # all chars from the format string 
my @format_array;      # if format_string='$AUTHOR$ {\bf 2}'
                       # then format array will be
                       # ('HASH_KEY_AUTHOR',' {\bf 2}')

@format_char_array = split(//, $FORMAT_STRING);

my $start_flag = 0; # when I see $ I do $start_flag=1
                    # when I see it again I do     =0
                    # I do it to cath al $xxxx$ things!  

my $counter=0;      # just counter for the @format_array
			      

my $char;

###print "-----\n";
foreach $char (@format_char_array)
{
    ###print "$char\n";
    if($char ne $reservedDOLLAR) # if it is NOT '$'
    { # add this char and don't bother yourself with it! 
      $format_array[$counter] = $format_array[$counter] . $char;
    }     
    else   # oooh, this is '$'
    { 
      if($start_flag == 0){$start_flag = 1}   #if it is start of command
      else{$start_flag = 0};                  #if it is end of command
      $counter++;
      if($start_flag == 1)                    #if this will be command 
                           #add HASH_KEY before the name of it!
         {$format_array[$counter] = $reservedHASH_KEY;};
      
    }
};
###print "-----\n";
###foreach $char (@format_array)
###{ print "|$char|\n"};

my $char1; my $post_author='';

my @author_fields; 
my $last_sep=''; # 'R.R.Stepanyan',$last_sep,'A.A.Subbotin' - example
my   @author_name_key; my @author_seps;

foreach $char (@format_array) 
{   ($char1) = ( $char =~ /$reservedHASH_KEY([^}]*)/ );
    # $char1=trim($char1);
    #$char=trim($char);
    $#author_fields = -1;
    if($char1 ne '')
    { if((not($char1 =~ m/$reservedAUTHOR/))&&($HASH_REFS{$char1} eq '')) #this is not author 
	# and this field is empty
      { if($optionsINSERT_EMPTY_FIELDS_SIGN)
          {print OUTTEX '{',$reservedEMTY_FIELD_SIGN,'}'}; #OUTTEX is opened!
        if($verbosity_level > 1) #complain about absence of field
	  {print STDERR "Field <$char1> in the record <$HASH_REFS{$reservedLABEL}> is empty!\n"};
      }
      elsif($char1 =~ m/$reservedAUTHOR/)      
      { ($post_author) = ($char1 =~ /$reservedAUTHOR([^\$]*)/); # what if after AUTHOR ??
	  @author_fields=split(//,$post_author);
      
          my $iaf=0; #number of names in one author (last, first, middle name = 3)
	  my $saf=0; #number of separators
	  my $start=0;
	  my $max_n_of_aut=0;#max num of authors to show. If 0 then unlimited!  ??????????
	  
	  my $and_word=''; #have to be before the last author if number of outhors>1
	  
	  while($author_fields[$start] =~ /^[0-9]+$/)
	  {$max_n_of_aut="$max_n_of_aut$author_fields[$start]";
	   $start++;  
	  };
	  
	  my $niaf;
	  $niaf=scalar(@author_fields);
	  $#author_name_key = -1; $#author_seps = -1; #to make them clean!
	  
	  for(my $ii=$start; $ii<$niaf; $ii++)
	  {    
	      if($author_fields[$ii] =~/^[A-Za-z]+$/)
	          {$author_name_key[$iaf] = "$reservedAUTHOR$author_fields[$ii]"; $iaf++; $saf++;}
	      elsif($author_fields[$ii] ne $reservedAND_SEPARATOR) 
	          {$author_seps[$saf] = "$author_seps[$saf]$author_fields[$ii]"}
	      else{$and_word = substr($post_author,$ii+1); 
	           $ii=$niaf+1; #to finish the loop
	          }
	  };
	  
	  $last_sep=$author_seps[$saf]; 
    
	  #Thus we have 
	  #  @author_name_key  - array of the type (AUTHORL, AUTHORF, AUTHORM)
	  #  @author_seps      - $author_seps[1] is what should be placed after AUTHORF, 0-th - after AUTHORL
	  #  $last_sep         - should be placed after the complete name of one person!	  
	      
          #print $HASH_REFS{'AUTHORL'} ;     
	  my $n_of_aut=0 ; my $schet=0; my @avtor;

          #HOW MANY AUTHOR WE HAVE??? We should find MAXIMUM!!
	  
          while($schet < scalar(@author_name_key) )    
	  {  @avtor = split(/\|/,$HASH_REFS{$author_name_key[$schet]}); #
	     if($n_of_aut < scalar(@avtor)){$n_of_aut = scalar(@avtor)}; #number of authors
	     $schet++; 
	  };
          # Now number of authors is in the $n_of_aut

	  
	  my $print_etal = 0;      #?????????????
	  if(($max_n_of_aut > 0)&&($max_n_of_aut < $n_of_aut)){$n_of_aut=$max_n_of_aut; $print_etal=1;}
	  # now number of authors to display is '$n_of_aut'!
	  
	  my $jj; #counter for all names of one author!
	  my $max_jj = scalar(@author_name_key);
	  
	  for(my $ii=0;$ii<$n_of_aut;$ii++)    # $ii is number of aut to display
	  {
	      for($jj=0;$jj<$max_jj  ;$jj++) # $jj  is counter of name of the same person
	      {
		  #print OUTTEX $author_seps[$jj];
		  @avtor = split(/\|/,$HASH_REFS{$author_name_key[$jj]});
		  @avtor = trim(@avtor);
		  if($avtor[$ii] ne ''){print OUTTEX $author_seps[$jj];
	      
		                        print OUTTEX $avtor[$ii];};
	      };
	      
	      
	      if($ii<$n_of_aut-2){print OUTTEX $last_sep;}; #for all except the last
	      if($ii == $n_of_aut-2)
	      {  if(($n_of_aut>2)||(trim($and_word) eq "")){print OUTTEX $last_sep};
	         if(($n_of_aut>1)&&($print_etal == 0)){print OUTTEX " $and_word ";}
	         
              };
	  };   
	  #print $last_sep;
	  if($print_etal){print OUTTEX $reservedET_AL;}
      }    
      else
      {
        print OUTTEX '{',$HASH_REFS{$char1},'}'
      };      
      
    
    }
    else{print OUTTEX $char};    
};
#print "\n";
};
#---------------------------------------------------
sub find_there_cites_and_substitute_them
#processes line like 'this was done in works \cite{qq,rt6,markus,work56}'
#from INPUT.tex
#into the  line like 'this was done in works $^{1-3,8}$'
#and writes it into OUTPUT.tex
{   
    my @out = @_    ;
    my $line=$out[0];
    
    my (@qguess, @qguess2);    #keeps lines like  "label1,label2,label3"
    my (@qresults,@qresults2); #must keep  numbers like "1,2,3"
    (my @qguess0) =( $line =~ /$CITE([^}]*)/gi ); #now there r all xxx from \cite{xxx} in this array
    (my @qguess00) =( $line =~ /$refCITE([^}]*)/gi ); #now there r all xxx from \refcite{xxx} in this array
    # if there are more than one \cite in this line, then number of elements in qguess>1
    
    #added 4 Oct (1.)
    chomp($line);
    #

    if((scalar(@qguess0)==0)&&(scalar(@qguess00)==0))
      {print OUTTEX "\n",trim($line); return}; # trim() - because  we do not want
                                               # spaces at the end!!!
#--------------    
    @qguess=trim(@qguess0); #???????????????  $dst =~ s/this/that/;
    my @current; 
    for(my $i=0; $i<scalar(@qguess); $i++)
    {   $#current=-1;
        @current = trim(split(/,/, $qguess[$i])) ;
        for(my $j=0; $j<scalar(@current);$j++)    
	{   # print OUTTEX $current[$j]," "  ;  
	    #  for( my $k=0; $k<scalar(@ALLREFS); $k++)
	    #   { if( $current[$j] eq $ALLREFS[$k]) {$qresults[$i] = "$qresults[$i]$k"}
	    #   };
	    if($qresults[$i] eq ''){$qresults[$i]="$REFSORDERED{$current[$j]}" ; }
	    else{$qresults[$i]="$qresults[$i]$reservedSEPARATORINCITE$REFSORDERED{$current[$j]}"}
	};  
    };
   ####### 
    @qguess2=trim(@qguess00); 
    my @current2; 
    for(my $i=0; $i<scalar(@qguess2); $i++)
    {   $#current2=-1;
        @current2 = trim(split(/,/, $qguess2[$i])) ;
        for(my $j=0; $j<scalar(@current2);$j++)    
	{   if($qresults2[$i] eq ''){$qresults2[$i]="$REFSORDERED{$current2[$j]}" ; }
	    else{$qresults2[$i]="$qresults2[$i]$reservedSEPARATORINCITE$REFSORDERED{$current2[$j]}"}
	};  
    };
#-------------    
    
    for(my $i=0; $i<scalar(@qresults); $i++)
    {  #print OUTTEX $qresults[$i],"|";
	my $this = "$CITE$qguess[$i]}"; 
	$qresults[$i] = &make_1234__1_4($qresults[$i]) ;
	my $that = sprintf("$REF_FORMAT",$qresults[$i]) ;

        # at this point one can change order of [.,;:] and \cite{}
        # because it has to be:  works.$^{1,3,7}$
        # instead of          :  works$^{1,3,7}$.
        # whereas in the source it is: works \cite{1,3,7}.
        # parameter $optionsREPLACE_POINT governes that
        # $what_we_call_point = '.,:;' includes all POINT-like characters

        # what we do: 
        # 1. divide $line into 3 parts: 1st = waht is before \cite
        #                               2nd = \cite{ } itself
        #                               3rd = what is after \cite{}
        #    so, if one had $line = 'word \cite{1}. After'
        #    then: $part1 = 'word '      $part2='\cite{1}'    $part3='. After'
        #
        # 2. make  $part3a=trim($part3) 
        # 3. take the first character from $place3a and 
        #    check if it is in $what_we_call_point
        # 4. if answer from 3 is YES:
        #       
        # 
       
        if($optionsREPLACE_POINT)
        { $line = ifmovepoint($this,$line) };

	$line =~ s/ $this/$that/; $line =~ s/$this/$that/;
    };


    for(my $i=0; $i<scalar(@qresults2); $i++)
    {  #print OUTTEX $qresults2[$i],"|";
	my $this = "$refCITE$qguess2[$i]}"; 
	$qresults2[$i] = &make_1234__1_4($qresults2[$i]) ;
	my $that = sprintf("$refREF_FORMAT",$qresults2[$i]) ;
        
	$line =~ s/ $this/$that/; $line =~ s/$this/$that/;
    };

    #now let us check, that $line has \n at the end. If it does not we have to add it
#    chomp($line); # just to be sure!!!
#    $line="$line\n";



    #added 4 Oct 2001
    #At this point we have to look if there is "so called point" at the beginning of the $line
    
    my $first_character_in_this_line = substr($line,0,1);
    if($first_character_in_this_line =~ /[$what_we_call_point]/) 
    {    print OUTTEX $line; }   
    else
    {    print OUTTEX "\n$line";}
    #end of added 4 Oct 2001

    # before 4 Oct it was just: print OUTTEX $line;
};   
#---------------------------------------------------
sub make_1234__1_4
{   
    my $line = @_[0];
    #print $line;
    my @LINE = trim(split(/$reservedSEPARATORINCITE/,$line));
    if(scalar(@LINE) < 3){ return $line;};
    # print "  ",$LINE[0], $LINE[1], "\n" ;
    $line = $LINE[0];
    my $currentseparator= $reservedSEPARATORINCITE;
    for(my $i=1; $i<scalar(@LINE); $i++)
    {
	if(($LINE[$i] != $LINE[$i-1]+1)||($i+1 == scalar(@LINE))||($LINE[$i] != $LINE[$i+1]-1))
	{   #$currentseparator= $reservedSEPARATORINCITE;
	    $line = "$line$currentseparator$LINE[$i]";$currentseparator= $reservedSEPARATORINCITE;
	}
	else
	{$currentseparator= $reservedMULTISEPARATORINCITE}
    };      
    
    return $line;
};
#---------------------------------------------------
sub order_this_list
{   #??? TO BE DONE!!!!!!! 
    #for(my $i=0; $i<scalar(@REFS); $i++){ print "$i ->>> $REFS[$i] --\n"};
    
    unless($ORDERING eq '')
    {    
       my $do_ordering=1;
       while($do_ordering)
       {   $do_ordering=0;
	   for(my $i=1; $i<scalar(@REFS); $i++)
	   {
	       if(&keyfield($REFS[$i-1]) gt &keyfield($REFS[$i]) ) 
	        {($REFS[$i-1], $REFS[$i]) = ($REFS[$i], $REFS[$i-1]); $do_ordering =1 }
	   }
       };
    };
    
    for(my $i=0; $i<scalar(@REFS); $i++){ $REFSORDERED{"$REFS[$i]"} = $i+1};
    #foreach $item (keys %REFSORDERED){ print  $item,"--->",$REFSORDERED{"$item"},"\n"}
};

sub  keyfield
{
    my $a = @_[0];
    
    foreach $item (@ALLREFS) 
    { 
	#   print ${$item}{"LABEL"},"-->",${$item}{"VOL"},"\n"; 
	if(${$item}{"$reservedLABEL"} eq $a) {return ${$item}{"$ORDERING"}}
    };    
    return '';
};
#---------------------------------------------------
sub trim {
    my @out = @_;
    for (@out) {
        s/^\s+//;
        s/\s+$//;
    }
    return wantarray ? @out : $out[0];
}
#########################################################


sub read_inline_arguments
{my $DD='--'; my $D='-';
 my $counter=0; my $current='';
 my $guess;

for($counter=0;$counter<scalar(@ARGV);$counter++)
{
 #print "$item \n";
 $current = $ARGV[$counter];
 
#------------------------------------------------------------
 #first check if it has '--' at the beginning
 ($guess) = ($current =~/$DD([^ ]*)/);
 if(($guess ne '')&&(substr($current,0,2) eq $DD))
 {  
    my $nothing=0;
    SWITCH: {
      if ($guess eq "help")   {&print_help_info;    exit(0);} 	
      if ($guess eq "version"){&print_version_info; exit(0);}  
	
      #options
      if ($guess eq "nobibitem") 
         { $optionsKEEP_BIBITEM_AND_CITE=0; last SWITCH; }
      if ($guess eq "not_insert_empty_field_sign") 
         { $optionsINSERT_EMPTY_FIELDS_SIGN=0 ; last SWITCH; }
      if ($guess eq "uselist") 
         { $optionsREFS_AS_TEX_LIST=1 ; last SWITCH; }
      if ($guess eq "movepoint") 
         { $optionsREPLACE_POINT=1 ; last SWITCH; }
       

      #reserved words
      if ($guess eq 'separator') 
         { $counter++;  $SEPARATOR=$ARGV[$counter]; last SWITCH; }
      if ($guess eq 'start_refs') 
         { my $itis=1; my $whatis='';
           $#STARTREFS=-1;
           while($itis)
           {
	       $counter++; 
               unless($counter < scalar(@ARGV)-1){$counter--;last SWITCH;}
               $whatis = $ARGV[$counter];
               if((substr($whatis,0,2) eq $DD)||(substr($whatis,0,1) eq $D))
               {$counter--; $itis=0;} 
               else{$STARTREFS[$itis-1] = $whatis; $itis++};
	   };
           if(scalar(@STARTREFS)<1){print STDERR "Invalid format of --start_refs option";}
           last SWITCH; 
         }
      if ($guess eq 'end_refs') 
         { my $itis=1; my $whatis='';
           $#ENDREFS=-1;
           while($itis)
           {
	       $counter++; 
               unless($counter < scalar(@ARGV)-1){$counter--;last SWITCH;}
               $whatis = $ARGV[$counter];
               if((substr($whatis,0,2) eq $DD)||(substr($whatis,0,1) eq $D))
               {$counter--; $itis=0;} 
               else{$ENDREFS[$itis-1] = $whatis; $itis++};
	   };
           if(scalar(@ENDREFS)<1){print STDERR "Invalid format of --end_refs option";}
           last SWITCH; 
         }
      if ($guess eq 'etal') 
         { $counter++;  $reservedET_AL=$ARGV[$counter]; last SWITCH; }
      if ($guess eq 'empty_field_sign') 
         { $counter++;  $reservedEMTY_FIELD_SIGN=$ARGV[$counter]; last SWITCH; }
    $nothing = 1;
    };
    if($nothing){print STDERR "Unknown option <$current>!!! Exiting!\n"; exit(1);}
    else{next};
   };
 #-------------------------------------------------------------------
 #second: check if it has '-' at the beginning
 ($guess) = ($current =~/$D([^ ]*)/);
 if(($guess ne '')&&(substr($current,0,1) eq $D))
 {  
    my $nothing=0;
    SWITCH: {
      #options
      if ($guess eq "h") 
         { &print_help_info; exit(0)}      
      if ($guess eq "o") 
         { $counter++; $OUT_TEX=$ARGV[$counter]; last SWITCH; }
      if ($guess eq "f") 
         { $counter++; $FORMAT_NAME=$ARGV[$counter]; last SWITCH; }
      if ($guess eq "d") 
         { my $itis=1; my $whatis='';
           while($itis)
           {
	       $counter++; 
               unless($counter < scalar(@ARGV)-1){$counter--;last SWITCH;}
               $whatis = $ARGV[$counter];
               if((substr($whatis,0,2) eq $DD)||(substr($whatis,0,1) eq $D))
               {$counter--; $itis=0;} 
               else{$REFS_FILES[$itis-1] = $whatis; $itis++};
	   };
           if(scalar(@REFS_FILES)<1){print STDERR "Invalid format of -d option";}
           last SWITCH; 
         }
      if ($guess eq "a") 
         { $counter++; $ABBR_NAME=$ARGV[$counter]; $optionsABBREVIATIONS=1; last SWITCH; }



      if ($guess eq "v") 
         { $counter++; $verbosity_level=$ARGV[$counter]; last SWITCH; }
      #reserved words
      #if ($guess eq 'etal') 
      #   { $counter++;  $reservedET_AL=$ARGV[$counter]; last SWITCH; }
    $nothing = 1;
    };
    if($nothing){print "Unknown option <$current>!!! Exiting!\n"; exit(1);}
    else{next};
 };
 #---------------------------------------------------------------------
 #so, this is not switch
 if($counter+1 != scalar(@ARGV))
    {print STDERR "Unknown option <$current>!!! Exiting!\n"; exit(1);}
 else{$TEX_NAME =  $current;}
}

};

#----------------------------------
sub check_for_important_arguments
{
    if($TEX_NAME eq ''){print STDERR "No input file!!! Exiting!\n"; exit(1);};
    if($OUT_TEX eq ''){$OUT_TEX = "biblio.$TEX_NAME"};
    if(scalar(@REFS_FILES) == 0)
      {print STDERR "You must select at least one refs dbase file with -d option!!!";
       print STDERR "Exiting!\n";   
       exit(1)
      };
    if(scalar(@STARTREFS) == 0)
      {print STDERR "You must select where I should start the bibliography (--start_refs)!!!";
       print STDERR "Exiting!\n";   
       exit(1)
      };
    if(scalar(@ENDREFS) == 0)
      {print STDERR "You must select where I should end the bibliography (--end_refs)!!!";
       print STDERR "Exiting!\n";   
       exit(1)
      }; 
      if($FORMAT_NAME eq ''){$FORMAT_NAME = $TEX_NAME};  
}; 
#-----------------------------------
sub  print_version_info
{
print "biblio v.$BIBLIO_VERSION \n";
print "Written by R.Stepanyan.\n\n";
print "This is free software. There is NO warranty! \n";
print "Redistribution of this software is covered by the terms of";
print "the GNU General Public License.\n";
print "For more information, please, contact rstepanyan\@yahoo.com\n";
};
#-----------------------------------
sub  print_help_info
{
print "biblio v.$BIBLIO_VERSION \n";
print "biblio [-o outfile] [-f formatfile] -d dbasefile(s) [other keys] filename.tex\n";
print "\n";
print "-v <number> - verbosity level (0-5)\n";
print "-h (--help) - this help\n";
print "--nobibitem, --uselist - see readme.1st file\n";
print "--version   - version information\n";
print "\n";
print "About the other parameters see readme.1st \n";
print "\n";
#print "\n";
};


##################################################################

sub ifmovepoint
# needs $this $line as arguments
# returns $line with changed order of \cite and [.,;etc]
{    my @allargs = @_;
     my $this = $allargs[0];
     my $line = $allargs[1];
          # 
          # let's do N 1 from our plan
          #
           my $part1; my $part2; my $part3;
           ($part1, $part3) = split(/$this/, $line);
           $part2 = $this;
             #print "$line\n";
             #print "|1:$part1|2:$part2|3:$part3|end\n\n";
          #
          # let's do N 2 from our plan
          #
	   my $part3a = trim($part3);
           if($part3a ne '')
           { 
            #
            # let's do N 3 from our plan 
            #
             my $first_in_part3 = substr($part3a,0,1); 
            #
            # let's do N 4 from our plan
            #  
         
             if($first_in_part3 =~ /[$what_we_call_point]/) 
                   # $first_in_part3 includes only characters from $what_we_call_poin 
             {
	         $line = trim($part1) . $first_in_part3 . substr($this,1) ." " . substr($part3a,1);
             };
           };
 return $line;
}

########################################################################
sub insert_abbreviations_of_journals # $OUTTEX must be opened already
{ my $aline='';
  if($optionsABBREVIATIONS==1)
  {  open(ABBR,"$ABBR_NAME");

     print OUTTEX "\n"; 

     while(<ABBR>)
     {  $aline = $_;
        print OUTTEX "$aline" 
     }
     close(ABBR);

     print OUTTEX "\n"; 
     return 0;
  }
  else 
  {  return 0;
  }
};
