#!/bin/awk -f 

#
#   REFERENCES -- bibliographic software
#   Copyright (C) 1995-2006  Volker Kiefel
#
#   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307
#   USA
#
#
#   EXCITE.AWK  --  extract reference numbers refno1, refno2 from
#   `\cite{refno1,refno2}' or `\cite[OptionalArgument]{refno1,refno2}'
#   entries in (a) LaTeX file(s) into records of a raw TBT-file
#   `* refno1 * *'
#
#   Usage:
#
#      awk -f ExHarv.awk texfile1.tex [texfile2.tex ...]
#
#   EXCITE allows to extract more than one reference number from a list of
#   numbers separated by `,'. The resulting `RCITE.TBT' file may be
#   converted into a TBT file and a list of references may be prepared for
#   the LaTeX `thebibliography' environment. If `RCITE.TBT' already exists,
#   reference numbers are appended.
#
#   Excite may also be used to collect the reference numbers from a LaTeX
#   document to prepare a bibliography database for BibTeX from REFERENCES.
#
#   Excite has been tested with GAWK, MAWK, Kernighan's AWK
#
#   Limitations: ExCite does not `understand' \input{filename}, instead you
#   have to name all files of a document at the command line or you have to
#   run the AWK-script several times with all TeX files constituting a
#   LaTeX-document.
#
#   ExHarv extracts reference numbers from the following constructs:
#
#   \cite{}, \cite[]{}, \citeasnoun{}, \citeasnoun[]{},
#   \possessivecite{}, \possessivecite[]{},
#   \citeaffixed{}{}, \citeaffixed[]{}{},
#   \citeyear{}, \citeyear[]{}, \citename{}, \citename[]{}
#

BEGIN {
  ctrefs = 0;
  helponly = 0;                                  # only view help
  outfle="rcite.tbt"                             # name of output file
  alter_name = "";
  if (ARGC < 2)
  {
    helponly=1;
    if (hilfe=="FROM_SCRIPT")
    {
      print "\nUSAGE: EXHARV FILE1.TEX [FILE2.TEX [FILEN.TEX]]\n"
    } else
    {
      print "\nUSAGE: " ARGV[0] " -f EXHARV.AWK FILE1.TEX [FILE2.TEX [FILEN.TEX]]\n"
    }
    exit(1);
  }
  printf("\n")
}

{
   inp = $0                                      # the current line
   if (FILENAME!=alter_name)
   {
     alter_name = FILENAME
     print FILENAME " ->  RCITE.TBT "
   }
   for (;;)
   {
      # am weitesten links liegendes Muster suchen
      muster = ""
      min_pos = length(inp)

      match(inp,/\\cite{[^}]*}/)                 # search \cite{...}
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "cite1"
             min_pos = RSTART
          }
      }
                                                 # search \cite[opt]{rn1,rn2}
      (match(inp,/\\cite\[[^]]*\]{[^}]*}/) >= 1)
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "cite2"
             min_pos = RSTART
          }
      }

      match(inp,/\\citeasnoun{[^}]*}/)                 # search \citeasnoun{...}
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "citeasnoun1"
             min_pos = RSTART
          }
      }
                                                 # search \citeasnoun[opt]{rn1,rn2}
      (match(inp,/\\citeasnoun\[[^]]*\]{[^}]*}/) >= 1)
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "citeasnoun2"
             min_pos = RSTART
          }
      }

      match(inp,/\\possessivecite{[^}]*}/)                 # search \possessivecite{...}
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "possessivecite1"
             min_pos = RSTART
          }
      }
                                                 # search \possessivecite[opt]{rn1,rn2}
      (match(inp,/\\possessivecite\[[^]]*\]{[^}]*}/) >= 1)
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "possessivecite2"
             min_pos = RSTART
          }
      }
      match(inp,/\\citeaffixed{[^}]*}{[^}]*}/)                 # search \citeaffixed{...}{}
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "citeaffixed1"
             min_pos = RSTART
          }
      }
                                                 # search \citeaffixed[opt]{rn1,rn2}{}
      (match(inp,/\\citeaffixed\[[^]]*\]{[^}]*}{[^}]*}/) >= 1)
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "citeaffixed2"
             min_pos = RSTART
          }
      }
      match(inp,/\\citeyear{[^}]*}/)                 # search \citeyear{...}
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "citeyear1"
             min_pos = RSTART
          }
      }
                                                 # search \citeyear[opt]{rn1,rn2}
      (match(inp,/\\citeyear\[[^]]*\]{[^}]*}/) >= 1)
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "citeyear2"
             min_pos = RSTART
          }
      }
      match(inp,/\\citename{[^}]*}/)                 # search \citename{...}
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "citename1"
             min_pos = RSTART
          }
      }
                                                 # search \citename[opt]{rn1,rn2}
      (match(inp,/\\citename\[[^]]*\]{[^}]*}/) >= 1)
      if (RSTART > 0)
      {
          if (RSTART < min_pos)
          {
             muster = "citename2"
             min_pos = RSTART
          }
      }

      if (muster=="cite1")
      {
         match(inp,/\\cite{[^}]*}/)       # search \cite{...}
         cite_ex = substr(inp,RSTART,RLENGTH)
         pat_start = RSTART
         pat_length = RLENGTH
         cite_exex = substr(cite_ex,length("\\cite{")+1,\
                     length(cite_ex)-length("\\cite{")-1)
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *"  >> outfle
             ctrefs++
         }

         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }

      else if (muster=="cite2")
      {                                          # search \cite[opt]{rn1,rn2}
         match(inp,/\\cite\[[^]]*\]{[^}]*}/)
         cite_ex = substr(inp,RSTART,RLENGTH)    # extr. \cite[opt]{rn1,rn2}
         pat_start = RSTART
         pat_length = RLENGTH
         match(cite_ex,/\\cite\[[^]]*\]{/)      # determine length of r. e.
         cite_exex = substr(cite_ex,RLENGTH+1,\
                     length(cite_ex)-RLENGTH-1) # extr. rn1,rn2

                                                 # separate rn1 rn2
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *" >> outfle
             ctrefs++
         }


         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }


      else if (muster=="citeasnoun1")
      {
         match(inp,/\\citeasnoun{[^}]*}/)       # search \citeasnoun{...}
         cite_ex = substr(inp,RSTART,RLENGTH)
         pat_start = RSTART
         pat_length = RLENGTH
         cite_exex = substr(cite_ex,length("\\citeasnoun{")+1, \
                     length(cite_ex)-length("\\citeasnoun{")-1)
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *"  >> outfle
             ctrefs++
         }

         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }

      else if (muster=="citeasnoun2")
      {                                          # search \citeasnoun[opt]{rn1,rn2}
         match(inp,/\\citeasnoun\[[^]]*\]{[^}]*}/)
         cite_ex = substr(inp,RSTART,RLENGTH)    # extr. \citeasnoun[opt]{rn1,rn2}
         pat_start = RSTART
         pat_length = RLENGTH
         match(cite_ex,/\\citeasnoun\[[^]]*\]{/)      # determine length of r. e.
         cite_exex = substr(cite_ex,RLENGTH+1,\
                     length(cite_ex)-RLENGTH-1)  # extr. rn1,rn2

                                                 # separate rn1 rn2
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *" >> outfle
             ctrefs++
         }


         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }
      else if (muster=="possessivecite1")
      {
         match(inp,/\\possessivecite{[^}]*}/)       # search \possessivecite{...}
         cite_ex = substr(inp,RSTART,RLENGTH)
         pat_start = RSTART
         pat_length = RLENGTH
         cite_exex = substr(cite_ex,length("\\possessivecite{")+1,\
                     length(cite_ex)-length("\\possessivecite{")-1)
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *"  >> outfle
             ctrefs++
         }

         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }

      else if (muster=="possessivecite2")
      {                                          # search \possessivecite[opt]{rn1,rn2}
         match(inp,/\\possessivecite\[[^]]*\]{[^}]*}/)
         cite_ex = substr(inp,RSTART,RLENGTH)    # extr. \possessivecite[opt]{rn1,rn2}
         pat_start = RSTART
         pat_length = RLENGTH
         match(cite_ex,/\\possessivecite\[[^]]*\]{/)      # determine length of r. e.
         cite_exex = substr(cite_ex,RLENGTH+1,  \
                     length(cite_ex)-RLENGTH-1)   # extr. rn1,rn2

                                                 # separate rn1 rn2
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *" >> outfle
             ctrefs++
         }


         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }
      else if (muster=="citeaffixed1")
      {
         match(inp,/\\citeaffixed{[^}]*}{[^}]*}/)       # search \citeaffixed{...}{}
         # cite_ex = substr(inp,RSTART,RLENGTH)
         pat_start = RSTART
         pat_length = RLENGTH
         match(inp,/\\citeaffixed{[^}]*}/)       # search \citeaffixed{...}
         cite_ex = substr(inp,RSTART,RLENGTH)

         cite_exex = substr(cite_ex,length("\\citeaffixed{")+1,\
                     length(cite_ex)-length("\\citeaffixed{")-1)
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *"  >> outfle
             ctrefs++
         }

         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }

      else if (muster=="citeaffixed2")
      {                                          # search \citeaffixed[opt]{rn1,rn2}{}
         match(inp,/\\citeaffixed\[[^]]*\]{[^}]*}{[^}]*}/)
         # cite_ex = substr(inp,RSTART,RLENGTH)    # extr. \citeaffixed[opt]{rn1,rn2}{}
         pat_start = RSTART
         pat_length = RLENGTH
         match(inp,/\\citeaffixed\[[^]]*\]{[^}]*}/)
         cite_ex = substr(inp,RSTART,RLENGTH)    # extr. \citeaffixed[opt]{rn1,rn2}
         match(cite_ex,/\\citeaffixed\[[^]]*\]{/)      # determine length of r. e.
         cite_exex = substr(cite_ex,RLENGTH+1,\
                     length(cite_ex)-RLENGTH-1)  # extr. rn1,rn2

                                                 # separate rn1 rn2
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *" >> outfle
             ctrefs++
         }


         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }
      else if (muster=="citeyear1")
      {
         match(inp,/\\citeyear{[^}]*}/)       # search \citeyear{...}
         cite_ex = substr(inp,RSTART,RLENGTH)
         pat_start = RSTART
         pat_length = RLENGTH
         cite_exex = substr(cite_ex,length("\\citeyear{")+1,\
                     length(cite_ex)-length("\\citeyear{")-1)
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *"  >> outfle
             ctrefs++
         }

         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }

      else if (muster=="citeyear2")
      {                                          # search \citeyear[opt]{rn1,rn2}
         match(inp,/\\citeyear\[[^]]*\]{[^}]*}/)
         cite_ex = substr(inp,RSTART,RLENGTH)    # extr. \citeyear[opt]{rn1,rn2}
         pat_start = RSTART
         pat_length = RLENGTH
         match(cite_ex,/\\citeyear\[[^]]*\]{/)      # determine length of r. e.
         cite_exex = substr(cite_ex,RLENGTH+1,\
                     length(cite_ex)-RLENGTH-1)   # extr. rn1,rn2

                                                 # separate rn1 rn2
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *" >> outfle
             ctrefs++
         }


         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }
      else if (muster=="citename1")
      {
         match(inp,/\\citename{[^}]*}/)       # search \citename{...}
         cite_ex = substr(inp,RSTART,RLENGTH)
         pat_start = RSTART
         pat_length = RLENGTH
         cite_exex = substr(cite_ex,length("\\citename{")+1,\
                     length(cite_ex)-length("\\citename{")-1)
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *"  >> outfle
             ctrefs++
         }

         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }

      else if (muster=="citename2")
      {                                          # search \citename[opt]{rn1,rn2}
         match(inp,/\\citename\[[^]]*\]{[^}]*}/)
         cite_ex = substr(inp,RSTART,RLENGTH)    # extr. \citename[opt]{rn1,rn2}
         pat_start = RSTART
         pat_length = RLENGTH
         match(cite_ex,/\\citename\[[^]]*\]{/)      # determine length of r. e.
         cite_exex = substr(cite_ex,RLENGTH+1,\
                     length(cite_ex)-RLENGTH-1)   # extr. rn1,rn2

                                                 # separate rn1 rn2
         nArr = split(cite_exex,cite_exex_Arr,"[ ,]")
         for (i=1;i<=nArr;i++)
         {
             print "* " cite_exex_Arr[i] " * *" >> outfle
             ctrefs++
         }


         inp = substr(inp,pat_start+pat_length)  # the next search with the
                                                 # rest of the line
      }

      else
      {
         break
      }
   }
}

END {
   if (helponly==0)
   {
    print "\nEXHARV wrote/appended " ctrefs " reference numbers to " outfle "\n"
    close(outfle)
   }
}
