#!/usr/bin/perl use strict; my $BIBLIST_VERSION = '1.2'; my @REFS_FILES = ('refers.db'); my @REFS; $REFS[0]=''; my @ALLREFS; my %REFSORDERED; my %ALLFORMATSTRINGS; my $CITE_FORMAT;my $REF_FORMAT; my $ORDERING=''; #must contain key-field, like AUTHORL, or TITLE my $reservedLABEL='LABEL'; my $reservedTYPE ='TYPE' ; my $reservedURL='URL'; my $reservedAUTHOR ='AUTHOR'; #must be in the form '5;' - 5=five authors must be shown. # ';'=1st author from the 2nd should be separated by ';' 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, .... #-------------------------------------- my $BIBITEM = '%'."\n".'\item'."\n".'% {'; 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 $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 %HASH_REFS; #CHANGE IT LATER!!! my $verbosity_level=1; # 5 is max my $optionsINSERT_EMPTY_FIELDS_SIGN = 1; my $optionsKEEP_BIBITEM_AND_CITE = 1; my $optionsHTML_OUTPUT = 0; my $optionsABBREVIATIONS =0; # use abbreviations tex-file my $httpprefix=''; my $OUT_TEX =''; #'allrefs.tex'; my $FORMAT_NAME ='';#'macromolecules';#$TEX_NAME; # file where all rules are! my $ABBR_NAME = 'abbr.tex'; #abbreviations file ##############################################3 &read_inline_arguments; &check_for_important_arguments; if ($verbosity_level > 0) {print "\nThis is biblist utility version $BIBLIST_VERSION\n"; print 'Author R.Stepanyan ',"\n\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"; my $REFS_FILE; foreach $REFS_FILE (@REFS_FILES) { &make_list_of_refs_in_dbase($REFS_FILE); #makes list of all refs in @REFS if($verbosity_level > 4) {print "read_ref_datafile <$REFS_FILE> first time: done...\n";} }; my $i=0; for($i=0; $i 4) {print "read_ref_datafile <$REFS_FILE> done...\n";} }; if($verbosity_level > 4){print "\n";} &order_this_list; if($verbosity_level > 4) {print "ordering of refs is done...\n";} if($optionsHTML_OUTPUT) { open(OUTTEX, "> $OUT_TEX"); print OUTTEX '',"\n"; print OUTTEX '',"\n"; print OUTTEX ' ',"\n"; print OUTTEX ' ',"\n"; print OUTTEX ' The bibliography list',"\n"; print OUTTEX '',"\n"; print OUTTEX '',"\n"; &insert_abbreviations_of_journals; print OUTTEX '
',"\n"; &print_all_references_into_tex_in_html_format; print OUTTEX '
',"\n"; print OUTTEX '',"\n"; print OUTTEX '',"\n"; print OUTTEX '',"\n"; print OUTTEX '',"\n"; print OUTTEX '',"\n"; print OUTTEX '',"\n"; print OUTTEX '',"\n"; close(OUTTEX); } else { open(OUTTEX, "> $OUT_TEX"); print OUTTEX '\documentstyle[12pt,a4]{article}',"\n"; #print OUTTEX '\documentstyle[aps,manuscript]{revtex}',"\n"; print OUTTEX '\title{List of references \\\ Generated by "biblist.pl"}',"\n"; print OUTTEX '\date{\today}',"\n"; print OUTTEX '\begin{document}\maketitle',"\n"; &insert_abbreviations_of_journals; print OUTTEX 'This list of references is generated from the following data-files:\newline',"\n",'\begin{center}{\it{'; for(my $RI=0; $RI ',$thecounter,'',"\n"; $thecounter++; print OUTTEX "No format string for TYPE \"$thetype\". Skipping record \"$item\"!\n"; print STDERR "No format string for TYPE <$thetype>. Skipping record <$item>!\n"; last; }; print OUTTEX "\n",'
',$thecounter,'
',"\n"; $thecounter++; #print $thetype,"-->",$ALLFORMATSTRINGS{"$thetype"}, "\n"; print OUTTEX '
'; &formated_output($ALLFORMATSTRINGS{"$thetype"},%{$item1}); #CHANGE $FORMAT_STRING1 HERE!!! if(${$item1}{"$reservedURL"} ne '') { print OUTTEX '
';} else{print OUTTEX $httpprefix,$theurl,'">';} print OUTTEX ${$item1}{"$reservedURL"}; print OUTTEX ''; }; 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_in_bibitem_format { my ($item1, $item); print OUTTEX '%Generated by biblio',"\n"; for(my $i=0;$i. 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 order_this_list { #??? TO BE DONE!!!!!!! #for(my $i=0; $i>> $REFS[$i] --\n"}; unless($ORDERING eq '') { my $do_ordering=1; while($do_ordering) { $do_ordering=0; for(my $i=1; $i",$REFSORDERED{"$item"},"\n"} }; sub keyfield { my $a = @_[0]; foreach my $item (@ALLREFS) { # print ${$item}{"LABEL"},"-->",${$item}{"VOL"},"\n"; if(${$item}{"$reservedLABEL"} eq $a) {return uc(${$item}{"$ORDERING"})} }; return ''; }; #--------------------------------------------------- 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 = ) { 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 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. Reference format=$REF_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() { 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 =~ /$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); }; #-------------------------------------- sub make_list_of_refs_in_dbase # { 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 = ) { 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) { my $REFS_N = scalar(@REFS); if(scalar(@fields)>2) { for(my $i=2;$i '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 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 read_inline_arguments {my $DD='--'; my $D='-'; my $counter=0; my $current=''; my $guess; for($counter=0;$counter!!! 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 } }; #---------------------------------- sub check_for_important_arguments { if($OUT_TEX eq ''){$OUT_TEX = "biblist.output.tex"}; 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($FORMAT_NAME eq '') {print STDERR "You must select one formats file with -f option!!!"; print STDERR "Exiting!\n"; exit(1) }; }; #----------------------------------- sub print_version_info { print "biblist v.$BIBLIST_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 "biblist v.$BIBLIST_VERSION \n"; print "biblist [-o outfile] [-f formatfile] -d dbasefile(s) [other keys] \n"; print "\n"; print "-v - verbosity level (0-5)\n"; print "-h (--help) - this help\n"; print "--version - version information\n"; print "\n"; print "About the other parameters see readme.1st \n"; print "\n"; #print "\n"; }; #---------------------------------------------------- sub trim { my @out = @_; for (@out) { s/^\s+//; s/\s+$//; } return wantarray ? @out : $out[0]; } #------------------------------------------------------------------------------ sub insert_abbreviations_of_journals # $OUTTEX must be opened already { my $aline=''; if($optionsABBREVIATIONS==1) { open(ABBR,"$ABBR_NAME"); if($optionsHTML_OUTPUT){print OUTTEX "
";} else{print OUTTEX "\n"; }; while() { $aline = $_; print OUTTEX "$aline" ; if($optionsHTML_OUTPUT){print OUTTEX "
";} ; } close(ABBR); if($optionsHTML_OUTPUT){print OUTTEX "
";} else{print OUTTEX "\n"; } return 0; } else { return 0; } };