Logo Search packages:      
Sourcecode: kbib version File versions  Download package

bibentry.cpp

/***************************************************************************
                          bibentry.cpp  -  description
                             -------------------
    begin                : Sat May 24 2003
    copyright            : (C) 2003 by Thach Nguyen
    email                : thach@dragon.thach.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <iostream>
#include <map>
#include <stdlib.h>
#include <ctype.h>
#include <vector>
using namespace std;


#include "bibentry.h"

#include <qstring.h>
#include <qstringlist.h>
#include <qstylesheet.h>
//extern int flag_allow_warnings;

int flag_allow_warnings = 0;

BibEntry::BibEntry()
{
      def = 0;
      req_field = 0;
      opt_field = 0;
      index = -1;
      nextra = 0;
}

BibEntry::BibEntry ( const QString n, const QString k )
{
      def = BibEntryDefTable::self()->getBibEntryDef ( n );

      key = k;

      if (!def)
            def = BibEntryDefTable::self()->getBibEntryDef ( QString::fromLatin1("other") );
      
      if ( def )
      {
//        special = false;
//          preamble = false;
//          stringMacro = false;
            req_field = new QString[def->numRequired() ];
            opt_field = new QString[def->numOptional() ];
            index = -1;
            asStringMacro = new bool[def->numRequired() +def->numOptional() ];
            for ( int i = 0; i < def->numRequired() +def->numOptional(); i++ )
                  asStringMacro[i] = false;
//        setField(QString::fromLatin1("lockkey"), "N");
      }

      nextra = 0;
}


00071 BibEntry::BibEntry ( BibEntry& bib )
{
      def = bib.def;
      key = bib.key;

//    special =  bib.special;
//    preamble = bib.preamble;
//    stringMacro = bib.stringMacro;
      index = bib.getIndex();

      if ( def )
      {
            req_field = new QString[def->numRequired() ];
            opt_field = new QString[def->numOptional() ];
            asStringMacro = new bool[def->numRequired() +def->numOptional() ];
      }
      /*    else if (special)
          {
              req_field = new string[1];
              opt_field = 0;
          }
      */
      nextra = 0;
      setFields ( bib );
}



BibEntry& BibEntry::operator= ( BibEntry &bib )
{
      if ( def )
      {
            delete[] req_field;
            delete[] opt_field;
            delete[] asStringMacro;
            extra_field.clear();
            extra_field_string_macro.clear();
      }

      def = bib.def;
      key = bib.key;

//    special =  bib.special;
//    preamble = bib.preamble;

      if ( def )
      {
            req_field = new QString[def->numRequired() ];
            opt_field = new QString[def->numOptional() ];
            asStringMacro = new bool[def->numRequired() +def->numOptional() ];
      }

      nextra = 0;
      setFields ( bib );
      return ( *this );
}


BibEntry::~BibEntry()
{
      if ( def )
      {
            if ( req_field )
                  delete[] req_field;
            if ( opt_field )
                  delete[] opt_field;
            if ( asStringMacro );
            delete[] asStringMacro;
      }
}

QString BibEntry::getEntryType() const
{
      if ( def )
            return def->name;
      else
            return QString::null;
}

void BibEntry::setEntryType ( QString et )
{
      BibEntry bib ( et, key );

      if ( def )
            bib.setFields ( *this );
      else
      {
            def = BibEntryDefTable::self()->getBibEntryDef ( et );
            if ( def )
            {
                  req_field = new QString[def->numRequired() ];
                  opt_field = new QString[def->numOptional() ];
            }
            else
            {
                  req_field = new QString[1];
                  opt_field = 0;
            }
            nextra = 0;
      }

      *this = bib;
}

QString BibEntry::getKey() const
{
      return key;
}

QString BibEntry::getFieldName ( int i ) const
{
      if ( !def )
            return 0;

      if ( i<0 || i >= getNoFields() )
            return 0;

      if ( i < def->numRequired() + def->numOptional() )
            return ( i < def->numRequired() ) ? def->getRequired ( i ) :
                   def->getOptional ( i - def->numRequired() );

      i -= def->numRequired() + def->numOptional();

      QMap<QString, QString>::ConstIterator it = extra_field.begin();
      for ( ; i > 0 && it!=extra_field.end(); i-- )
      {
            it++;
      }
      return it.key();
}

QString BibEntry::getField ( const QString fn ) const
{
      if ( fn.lower() == QString::fromLatin1 ( "citation key" ) )
            return key;

      int x=getNoFields();

      for ( int i=0; i< x; i++ )
      {
            if ( fn.lower() == getFieldName ( i ).lower() )
            {
                  return getField ( i );
            }
      }
      return 0;
}

bool BibEntry::stringMacroIndicator ( QString fieldnamex )
{
      QString fieldname = fieldnamex.lower();

      int i = def->getFieldIdx ( fieldname );
      if ( i>=0 )
      {

            return asStringMacro[i];
      }
      else
      {
            QMap<QString, bool>::Iterator it = extra_field_string_macro.begin();
            for ( ; it!=extra_field_string_macro.end(); it++ )
            {
                  if ( ( it.key() ).lower() == fieldname ){
                        return it.data();
                  }
            }
            return false;
      }
}



QString BibEntry::getField ( int i ) const
{
      if ( !def )
            return ( i==0 ) ?  req_field[i] : 0;

      if ( i<0 || i >= getNoFields() )
            return 0;
      if ( i < def->numRequired() + def->numOptional() )
      {
            return ( i < def->numRequired() ) ? req_field[i] :
                   opt_field[i - def->numRequired() ];
      }
      i -= def->numRequired() + def->numOptional();
      QMap<QString, QString>::ConstIterator it = extra_field.begin();
      for ( ; i > 0 && it!=extra_field.end(); i-- )
            it++;
      return it.data();
}

QString BibEntry::getReqField ( int i ) const
{
      return ( i < def->numRequired() ) ? req_field[i] : 0;
}


QString BibEntry::getOptField ( int i ) const
{
      return ( i < def->numOptional() ) ? opt_field[i] : 0;
}

QString BibEntry::getExtField ( int i ) const
{

      int index = 0;
      QMap<QString, QString>::ConstIterator it = extra_field.begin();
      for ( ; it!=extra_field.end(); ++it )
      {
            if ( index == i )
                  return it.data();
            index++;
      }


      return 0;
}


void BibEntry::setField ( int i, QString field )
{
      if ( i < 0 || i >= getNoFields() )
            return;

      if ( !def && req_field )
      {
            req_field[0] = field;
            return;
      }


      //    cerr << "sField " << key << ":" << i << ": " << field << "\n";
      if ( i < def->numRequired() )
      {
            req_field[i] = field;
      }
      else
      {
            if ( i < def->numRequired() + def->numOptional() )
            {
                  opt_field[i - def->numRequired() ] = field;
            }


            /*        else
                    {
                        i -= def->numRequired() + def->numOptional();
                              QMap<QString, QString>::Iterator it = extra_field.begin();
                        for (; i > 0 && it!=extra_field.end(); i--)
                                    it++;
                              it.data() = field;
                        }
            */
      }

}

void BibEntry::setField ( QString fieldnamex, QString field )
{
      //Convert fieldname to lowercaseless_findBibEntryBibEntry
      QString fieldname = fieldnamex.lower();

      if ( !def && req_field )
      {
            req_field[0] = field;
            return;
      }

      int i = def->getFieldIdx ( fieldname );

      if ( i>=0 )
      {
            setField ( i, field );
            //    cerr << key << ":Field " << fieldname << "|" << field << "\n";
      }
      else
      {
            if ( flag_allow_warnings )
                  cerr << "Warning " << key << ": Ignored field \"" << fieldname
                  << "\" in the entry type <" << getEntryType() << ">.\n";
            if ( !extra_field.contains ( fieldname ) ){
                  nextra++;
                  //create macro indicator storage location
                  extra_field_string_macro.insert ( fieldname, false );
            }
            extra_field.insert ( fieldname, field );
      }
}


void BibEntry::setStringMacroIndicator ( QString fieldnamex, bool s )
{
      //Convert fieldname to lowercaseless_findBibEntryBibEntry
      QString fieldname = fieldnamex.lower();

      int i = def->getFieldIdx ( fieldname );

      if ( i>=0 )
      {
            setStringMacroIndicator ( i, s );
      }
      else
      {
            //if (flag_allow_warnings)
            //cerr << "Set string warning " << key << ": Ignored field \"" << fieldname << "\" in the entry type <" << getEntryType() << ">.\n";
            extra_field_string_macro.insert ( fieldname, s );
      }
}

/*
void BibEntry::setFields(BibEntry &entry)
{
      clearExtraField();
      for (int i=0; i<entry.getNoFields(); i++)
    {
        string s = entry.getField(i);
        //if (!s.empty()) {
        setField(entry.getFieldName(i), const_cast<char*>(s.c_str()));
        int j = def->getFieldIdx(entry.getFieldName(i));
        if (j >= 0)
            asStringMacro[j] = entry.stringMacroIndicator(i);
            else
                  setStringMacroIndicator(entry.getFieldName(i), entry.stringMacroIndicator(entry.getFieldName(i)) );
        //}
    }
}
*/


void BibEntry::setFields ( BibEntry &entry )
{
      clearExtraField();
      //Clear all main field;
      for ( int i = 0; i< ( getNoReqFields() + getNoOptFields() ); i++ )
      {
            setField ( i, 0 );
            setStringMacroIndicator ( i, false );
      }

      for ( int i=0; i< ( entry.getNoReqFields() + entry.getNoOptFields() ); i++ )
      {
            QString st = entry.getField ( i );
            if ( !st.isEmpty() )
            {
                  setField ( entry.getFieldName ( i ), entry.getField ( i ) );
                  setStringMacroIndicator ( entry.getFieldName ( i ), entry.stringMacroIndicator ( entry.getFieldName ( i ) ) );
            }

      }

      for ( int i = 0; i < entry.getNoExtraFields(); i++ )
      {
            int j = i+entry.getNoReqFields() + entry.getNoOptFields();
            QString st = entry.getField ( j );
            if ( !st.isEmpty() )
            {
                  setField ( entry.getFieldName ( j ), st );
                  setStringMacroIndicator ( entry.getFieldName ( j ), entry.stringMacroIndicator ( entry.getFieldName ( j ) ) );
            }

      }


}



int BibEntry::createKey ( QString connectingString )
{
      QString fn = getField ( "lockkey" );
      if ( fn == QString::fromLatin1 ( "Y" ) )
            return -1;

      QString authors = getField ( QString::fromLatin1 ( "author" ) );

      if ( authors.isEmpty() )
      {
            //if (strlen(authors)==0){
            authors = getField ( "editor" );
      }
      if ( !authors.isEmpty() )
      {
            QString firstAuthor = ( QString ( authors ).stripWhiteSpace() ).section ( "and", 0, 0 );
            firstAuthor = firstAuthor.stripWhiteSpace();
            QString firstAuthorSurname;
            if ( firstAuthor.contains ( ',' ) )
            {
                  firstAuthorSurname = firstAuthor.section ( ',', 0, 0 );

            }
            else
                  firstAuthorSurname = firstAuthor.section ( ' ', -1, -1 );
            key = firstAuthorSurname + connectingString + getField ( QString::fromLatin1 ( "year" ) );
            return 1;
      }
      return 0;
}


int BibEntry::getIndex()
{
      return index;
}

void BibEntry::setIndex ( int i )
{
      index = i;
}

bool BibEntry::replaceString ( bool allField, QString field, QString oldString, QString newString )
{
      if ( oldString == newString )
            return false;
      QString oldValue;
      QString newValue;
      bool change = false;
      if ( allField )
      {
            for ( int i=0; i<getNoFields(); i++ )
            {
                  oldValue = getField ( i );
                  if ( oldValue.contains ( oldString ) > 0 )
                  {
                        newValue = oldValue.replace ( oldString, newString );
                        QString fn = getFieldName ( i );
                        setField ( fn, newValue );
                        change = true;
                  }
            }

      }
      else
      {
            if (field.isEmpty())
                  return false;
            oldValue = getField ( field );
            if ( oldValue )
            {
                  if ( oldValue.contains ( oldString ) > 0 )
                  {
                        newValue = oldValue.replace ( oldString, newString );
                        setField ( field, newValue );
                        change = true;
                  }
            }

      }
      return change;
}

int compareBibEntry ( BibEntry *entry1, BibEntry *entry2, int fields, bool compare_key, bool compare_lockkey )
{
      //return 1 if different, 0 if identical
      QString st1, st2;

      st1 = QString ( entry1->getEntryType() ).lower();
      st2 = QString ( entry2->getEntryType() ).lower();

      if ( st1 != st2 )
            return 1;

      QString entryTypeName = entry1->getEntryType();
      BibEntryDef *entryType = BibEntryDefTable::self()->getBibEntryDef ( entryTypeName );

      if ( compare_key )
      {
            st1 = entry1->getKey().lower();
            st2 = entry2->getKey().lower();
            if ( st1 != st2 )
                  return 1;
      }

      for ( int i=0; i < entryType->numRequired(); i++ )
      {

            st1 = ( QString ( entry1->getField ( entryType->getRequired ( i ) ) ).lower() ).simplifyWhiteSpace();
            st2 = ( QString ( entry2->getField ( entryType->getRequired ( i ) ) ).lower() ).simplifyWhiteSpace();
            if ( QString ( entryType->getRequired ( i ) ) == QString ( "author" ) || QString ( entryType->getRequired ( i ) ) == QString ( "editor" ) )
            {
                  st1 = reformatAuthors ( st1, 0 );
                  st2 = reformatAuthors ( st2, 0 );
            }
            if ( st1 != st2 )
                  return 1;
      }

      if ( fields == 1 || fields==2 )
      {
            for ( int i=0; i < entryType->numOptional(); i++ )
            {
                  st1 = ( QString ( entry1->getField ( entryType->getOptional ( i ) ) ).lower() ).simplifyWhiteSpace();
                  st2 = ( QString ( entry2->getField ( entryType->getOptional ( i ) ) ).lower() ).simplifyWhiteSpace();

                  if ( QString ( entryType->getOptional ( i ) ) == QString ( "author" ) || QString ( entryType->getOptional ( i ) ) == QString ( "editor" ) )
                  {
                        st1 = reformatAuthors ( st1, 0 );
                        st2 = reformatAuthors ( st2, 0 );
                  }

                  if ( QString ( entryType->getOptional ( i ) ).lower() == QString ( "lockkey" ) )
                  {
                        if ( compare_lockkey )
                        {
                              if ( st1 != st2 )
                                    return 1;
                        }
                  }

                  else
                  {
                        if ( st1 != st2 )
                              return 1;
                  }
            }

      }

      if ( fields == 2 )
      {
            if ( entry1->getNoExtraFields() != entry2->getNoExtraFields() )
                  return 1;
            else
            {
                  for ( int i = 0; i < entry1->getNoExtraFields(); i++ )
                  {
                        st1 = ( QString ( entry1->getField ( entryType->numRequired() + entryType->numOptional() + i ) ).lower() ).simplifyWhiteSpace();
                        st2 = ( QString ( entry2->getField ( entry1->getFieldName ( entryType->numRequired() + entryType->numOptional() + i ) ) ).lower() ).simplifyWhiteSpace();

                        if ( st1 != st2 )
                              return 1;
                  }

            }

      }
      return 0;
}


void processAuthor ( QString st, QString &surname, QString &givenname )
{
      QString author = ( st.simplifyWhiteSpace() );

      /*    author = author.lower();
          QChar c = author.at(0);
          author = author.replace(0, 1, c.upper());

          int i = 0;
          while(i!=-1)
          {
                  i=author.find(QString(" "), i+1);
                  c = author.at(i+1);
                  author = author.replace(i+1, 1, c.upper());
          }

          i = 0;
          while(i!=-1)
          {
                  i=author.find(QString("-"), i+1);
                  c = author.at(i+1);
                  author = author.replace(i+1, 1, c.upper());
          }
      */
      if ( author.contains ( ',' ) )
      {
            surname = author.section ( ',', 0, 0 );
            givenname = author.section ( ',', 1, 1 );
      }
      else
      {
            surname = author.section ( ' ', -1, -1 );
            givenname = author.section ( ' ', -100, -2 );
      }
      surname = surname.simplifyWhiteSpace();
      givenname = givenname.simplifyWhiteSpace();

}


QString reformatAuthors ( QString st, int numAuthorsDisplayed )
{
      QStringList authors = QStringList::split ( " and ", st );
      QString formatedAuthors=QString ( "" );
      bool first = true;
      int num=0;
      for ( QStringList::Iterator it = authors.begin(); it != authors.end(); ++it )
      {
            QString author = ( *it );

//        author = (author.simplifyWhiteSpace()).lower();
            author = author.simplifyWhiteSpace();
            QString surname, givenname;
            processAuthor ( author, surname, givenname );

            if ( givenname.isEmpty() )
                  author = surname;
            else author = surname + QString ( ", " ) + givenname;

            /*        author = author.lower();
                    QChar c = author.at(0);
                    author = author.replace(0, 1, c.upper());

                    int i = 0;
                    while(i!=-1)
                    {
                        i=author.find(QString(" "), i+1);
                        c = author.at(i+1);
                        author = author.replace(i+1, 1, c.upper());
                    }
            */
            if ( first )
                  formatedAuthors = author;
            else
                  formatedAuthors = formatedAuthors + " and " + author;
            first = false;
            num++;
            if ( numAuthorsDisplayed > 0 )
            {
                  if ( numAuthorsDisplayed >= ( int ) ( authors.count() ) && num == ( int ) ( authors.count() ) )
                        break;
                  else if ( numAuthorsDisplayed == num )
                  {
                        formatedAuthors = formatedAuthors + " et al";
                        break;
                  }
            }
      }
      return formatedAuthors;
}




QString entryToString ( BibEntry *e, int fieldDelimiter )
{
      QString ld, rd;
      switch ( fieldDelimiter )
      {
            case 1:
                  rd = ld="\"";
                  break;
            case 2:
                  ld = "(";
                  rd = ")";
                  break;
            default:
                  ld = "{";
                  rd = "}";
                  break;
      }
      QString st;
      st=st+"@"+e->getEntryType() +"{"+e->getKey();
      for ( int j=0; j < e-> getNoFields(); j++ )
      {
            if ( ! ( ( QString ( e->getField ( j ) ) ).simplifyWhiteSpace() ).isEmpty() )
            {
                  if ( e->stringMacroIndicator ( e->getFieldName ( j ) ) )
                        st=st+",\n\t"+e->getFieldName ( j ) +"="+e->getField ( j );
                  else
                        st=st+",\n\t"+e->getFieldName ( j ) +"="+QString ( ld ) +e->getField ( j ) +QString ( rd );
            }

      }
      st=st+"\n}\n";
      return st;
}


Generated by  Doxygen 1.6.0   Back to index