#!/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
#
#
#   group-num-cit.awk  --  extracts numeric citations in the manuscript 
#   text framed in `///', sorts the numbers, groups them and writes them 
#   into a raw `search and replace' macro:
#    
#   ...///1, 4, 5, 3, 2, 20///... -> 1, 4, 5, 3, 2, 20
#   -> ///A///1, 4, 5, 3, 2, 20///B///1-5, 20///C///
#
#   Usage:
#
#      awk [-v output_file=NameOfOutputFile.txt] -f group-num-cit.awk texfile
#   
#   macro file is written to the name assigned to outfle.
#
#

#   Versions:
#   15.7.2005: name of `outfle' may be changed (for References v4.2)
#   13.9.2005: script made 'portable' (sorts() instead of asort())

BEGIN {
   if (!output_file)
   {
     outfle = "numgr.txt"
   } else
   {
     outfle=output_file
   }
}


{
   zeile = $0
   for (;;)
   {
      if (match(zeile,/\/\/\/[^\/]*\/\/\//))
      {
         pat_start = RSTART
         pat_length = RLENGTH
         liste_gross = substr(zeile,RSTART,RLENGTH)
         liste_klein = substr(liste_gross,length("///")+1,length(liste_gross)-2*length("///"))
         liste_neu = convert_number_list(liste_klein)
         printf("///A///%s///B///%s///C///\n",liste_klein,liste_neu) > outfle
         if (length(zeile) > pat_length)
         {
            #zeile = substr(zeile,pat_start+pat_length)
            res = substr(zeile,pat_start+pat_length-1)
            zeile = res
         }
         else
         {
            break
         }
      }
      else
      {
          break
      }
   }

}


function convert_number_list(inzeile,   i, anzahl_zahlen, aus)
{
   #anzahl_zahlen = split(inzeile, ar, ", ")
   anzahl_zahlen = split(inzeile, ar,/\,[\ ]*/)

   # asort(ar)
   sorts(ar,anzahl_zahlen)
   
   # put numbers into every 2nd field of br
   for (i=1;i<=anzahl_zahlen;i++)
   {
      br[2*i-1] = ar[i]
   }
   # put "-" between fields with difference 1, otherwise ", "
   for (i=2;i<2*anzahl_zahlen;i=i+2)
   {
      if ((br[i+1]-br[i-1])==1)
      {
          br[i] = "-"
      }
      else
      {
          br[i] = ", "
      }
   } 
   
   # in case of
   #   1-2-3 (5 fields in br)
   # remove fields 2 and 3 (by assigning ""):
   #   1-3
   
   for (i=2+1;i<=2*anzahl_zahlen-3;i=i+2) 
   {
      if ((br[i-1]=="-") && (br[i+1]=="-"))
      {
         br[i-1]=""
         br[i]=""
      }
   }
   
   aus=""
   for (i=1;i<2*anzahl_zahlen;i++)
    
   {
      aus = aus br[i]
   }
   return aus
}


function sorts(ARRAY, ELEMENTS,        i, j, h, temp)
{
  h = 1;
  do {
    h *= 3 ;
    h++;
  } while (h <= ELEMENTS)

  do {
     h /= 3 ;
     h = int(h);

     for (i = h+1; i <= ELEMENTS; i++) {
        temp = ARRAY[i] ;
        j = i ;
        while (ARRAY[j-h] > temp) {
          ARRAY[j]=ARRAY[j-h] ;
          j -= h ;
          if (j <= h)  break;
        }
        ARRAY[j] = temp
     }
  } while (h > 1)
}


END {
   print "\nMacro written to `"  outfle "'\n"
   close(outfle)
}

