"Fossies" - the Fresh Open Source Software Archive

Member "cb2bib-2.0.1/src/c2b/coreBibParser.h" (12 Feb 2021, 7026 Bytes) of package /linux/privat/cb2bib-2.0.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "coreBibParser.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.0.0_vs_2.0.1.

    1 /***************************************************************************
    2  *   Copyright (C) 2004-2021 by Pere Constans
    3  *   constans@molspaces.com
    4  *   cb2Bib version 2.0.1. Licensed under the GNU GPL version 3.
    5  *   See the LICENSE file that comes with this distribution.
    6  ***************************************************************************/
    7 #ifndef COREBIBPARSER_H
    8 #define COREBIBPARSER_H
    9 
   10 #include "authorString.h"
   11 #include "bibReference.h"
   12 #include "settings.h"
   13 #include "txtmatcher.h"
   14 
   15 #include <QDir>
   16 #include <QObject>
   17 
   18 
   19 /**
   20     Class for bibliographic reference parsing
   21 
   22     @author Pere Constans
   23 */
   24 class coreBibParser : public QObject
   25 {
   26 
   27     Q_OBJECT
   28 
   29 public:
   30     explicit coreBibParser(QObject* parento = 0);
   31     inline virtual ~coreBibParser() {}
   32 
   33     QString referenceToBibTeX(const bibReference& ref) const;
   34     QString referenceToFomattedBibTeX(const bibReference& ref) const;
   35     QString singleReferenceField(const QString& field, const bibReference& ref) const;
   36     bibReference wholeReference(const QString& str) const;
   37     bool referenceAtKey(const QString& key, const QString& str, bibReference* ref);
   38     bool referencesIn(const QString& str, bibReference* ref);
   39     void initReferenceParsing(const QString& dir, const QStringList& fields, bibReference* ref);
   40 
   41     inline const QStringList& bibliographicFields() const
   42     {
   43         return _bibliographic_fields;
   44     }
   45     inline const QStringList& sortedBibliographicFields() const
   46     {
   47         return _sorted_bibliographic_fields;
   48     }
   49     inline const QStringList& bibliographicTypes() const
   50     {
   51         return _bibliographic_types;
   52     }
   53     inline void setReferenceParsingDir(const QString& dir)
   54     {
   55         // Set base dir for cases of relative 'file'
   56         // Terminate dirname with separator to avoid adding it to each reference
   57         _bib_file_dir = QDir::toNativeSeparators(QFileInfo(dir).absolutePath() + QDir::separator());
   58     }
   59     inline bool hasBibTeX(const QString& str) const
   60     {
   61         if (_bib_begin0_re.indexIn(str) > -1)
   62             return true;
   63         else
   64             return _bib_begin1_re.indexIn(str) > -1;
   65     }
   66     inline int fieldCount(const bibReference& ref) const
   67     {
   68         // Counting non empty fields
   69         int n(0);
   70         bibReferenceIterator i;
   71         for (i = ref.constBegin(); i != ref.constEnd(); ++i)
   72             if (!i.value().isEmpty())
   73                 ++n;
   74         return n;
   75     }
   76     inline QString& authorFromBibTeX(QString& as)
   77     {
   78         // Avoid BibTeX reverse names
   79         if (as.contains(_comma))
   80             as = _authorString.toBibTeX(as, _settingsP->value("cb2Bib/UseFullNames").toBool());
   81         return as;
   82     }
   83     inline QString authorFromMedline(const QString& author) const
   84     {
   85         return _authorString.fromMedline(author);
   86     }
   87     inline const QString& authorPrefixes() const
   88     {
   89         return _authorString.prefixes();
   90     }
   91 
   92 
   93 protected:
   94     QRegExp _field_re;
   95     QString adjacentNumbers(const QString& numbers) const;
   96     QStringList _bibliographic_fields;
   97     QStringList _bibliographic_types;
   98     QStringList _current_bibliographic_fields;
   99     QStringList _sorted_bibliographic_fields;
  100     authorString _authorString;
  101     settings* _settingsP;
  102 
  103 
  104 private:
  105     QRegExp _bib_begin0_re;
  106     QRegExp _bib_begin1_re;
  107     QRegExp _bib_begin_re;
  108     QString _bib_file_dir;
  109     const QChar _at;
  110     const QChar _close;
  111     const QChar _colon;
  112     const QChar _comma;
  113     const QChar _cr;
  114     const QChar _hyphen;
  115     const QChar _lca;
  116     const QChar _lcz;
  117     const QChar _nl;
  118     const QChar _open;
  119     const QChar _period;
  120     const QChar _pound;
  121     const QChar _quote;
  122     const QChar _space;
  123     const QChar _tilde;
  124     const QChar _uca;
  125     const QChar _ucz;
  126     txtmatcher _bib_begin_at;
  127     txtmatcher _bib_field_delimiter;
  128 
  129     void referenceContents(const QString& str, bibReference* ref, int pos) const;
  130     void setFields();
  131     void setRegularExpressions();
  132     void setTypes();
  133 
  134     void _parse_reference_fields(const QString& bibstr, const QStringList& fields, bibReference* ref) const;
  135     int _in_braces_ends(const QChar* const b, const int p, const int length) const;
  136 
  137     inline int referenceStarts(const QString& str, int pos = 0) const
  138     {
  139         while (true)
  140         {
  141             const int i(_bib_begin_at.indexIn(str, pos));
  142             if (i > 0)
  143             {
  144                 for (int j = i - 1; j >= pos; --j)
  145                     if (str.at(j) == _nl || str.at(j) == _cr)
  146                         goto check;
  147                     else if (!str.at(j).isSpace())
  148                         goto next;
  149                 if (pos > 0)
  150                     goto next;
  151             }
  152             else if (i < 0)
  153                 return i;
  154 check:
  155             if (_bib_begin_re.indexIn(str, i, QRegExp::CaretAtOffset) == i)
  156                 return i;
  157 next:
  158             pos = i + 2;
  159         }
  160     }
  161     inline int referenceStarts(const QString& key, const QString& str) const
  162     {
  163         if (!str.contains(key))
  164             return -1;
  165         int i(str.indexOf(QRegExp("^\\s*@\\w+\\s*\\{" + key + ',')));
  166         if (i < 0)
  167             i = str.indexOf(QRegExp("[\\r\\n]\\s*@\\w+\\s*\\{" + key + ','));
  168         if (i < 0)
  169             return i;
  170         return str.indexOf(QRegExp("@\\w+\\s*\\{" + key + ','), i);
  171     }
  172     inline int referenceEnds(const QString& str, const int pos = 0) const
  173     {
  174         // If referenceStarts call is successful, we know for sure
  175         // that there is an opening { right after pos.
  176         // Do not check again here.
  177         // Checking for brace closure is the safest way for parsing.
  178         // It will fail, though, for references incorrectly written.
  179         // Avoid overextending in these cases by checking the
  180         // start of the next reference.
  181         int ref_length(referenceStarts(str, pos + 2) - 1);
  182         if (ref_length < 0)
  183             ref_length = str.length();
  184         const int brace_pos(str.indexOf(_open, pos));
  185         int open_braces(1);
  186         for (int i = brace_pos + 1; i < ref_length; ++i)
  187         {
  188             if (str.at(i) < _open)
  189                 continue;
  190             const QChar& si(str.at(i));
  191             if (si == _open)
  192                 open_braces++;
  193             else if (si == _close)
  194                 open_braces--;
  195             if (open_braces == 0)
  196                 return i;
  197         }
  198         return ref_length - 1;
  199     }
  200     inline void setReferenceEnd(QString* str) const
  201     {
  202         // Set safer termination: field="..." } -> field="...",}
  203         const unsigned int length(str->length());
  204         if (str->at(length - 2) == _space)
  205             (*str)[length - 2] = _comma;
  206         else
  207             (*str)[length - 1] = _comma;
  208     }
  209     inline QString referenceAt(const QString& str, int* pos) const
  210     {
  211         // String str contains one or multiple references (file contents)
  212         const int p(referenceEnds(str, *pos) + 1);
  213         const QString str_ref(str.mid(*pos, p - (*pos)));
  214         *pos = p;
  215         return str_ref;
  216     }
  217 };
  218 
  219 #endif