"Fossies" - the Fresh Open Source Software Archive

Member "cb2bib-2.0.1/src/c2b/idMaker.cpp" (12 Feb 2021, 10280 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 "idMaker.cpp" 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  *   Improvements and modifications:
    8  *   July 2009 - Added <<author_all_abbreviated>>, (C) 2009 by Dayu Huang
    9  ***************************************************************************/
   10 #include "idMaker.h"
   11 
   12 #include "settings.h"
   13 
   14 
   15 idMaker::idMaker(const QString& patternKey, QObject* parento) : QObject(parento), _pattern_key(patternKey)
   16 {
   17     loadSettings();
   18     connect(settings::instance(), SIGNAL(newSettings()), this, SLOT(loadSettings()));
   19 }
   20 
   21 
   22 /** \page predefinedplaceholders Predefined Placeholders
   23 
   24 
   25   \section idplaceholders Cite and Document ID Placeholders
   26 
   27 
   28     - <tt><<author_all_abbreviated>></tt> Takes first three letters of the last
   29     word of all authors's last name in cite, and converts to lowercase.
   30 
   31     - <tt><<author_all_initials>></tt> Takes capitalized initials of all
   32     authors in cite.
   33 
   34     - <tt><<author_first>></tt> Takes first author last name.
   35 
   36     - <tt><<author_first_lowercase>></tt> Takes first author last name in
   37     lowercase.
   38 
   39     - <tt><<citeid>></tt> This placeholder is meant to be used <b>alone, and
   40     only for document IDs</b>. It takes the pattern defined for the cite ID. If
   41     the cite ID is modified manually, the document ID is synchronized
   42     automatically.
   43 
   44     - <tt><<journal_initials>></tt> Takes capitalized initials of journal name.
   45 
   46     - <tt><<pages_first>></tt> First page.
   47 
   48     - <tt><<ppages_first>></tt> First page, written as, e. g., 'p125'.
   49 
   50     - <tt><<title>></tt> Title. To truncate titles exceeding a maximum length
   51     <tt>l</tt> use <tt><<title_l>></tt>, where <tt>l</tt> stands for an integer
   52     value.
   53 
   54     - <tt><<title_underscored>></tt> Title with blanks set to underscores. To
   55     truncate title to <tt>l</tt> characters use
   56     <tt><<title_underscored_l>></tt>.
   57 
   58     - <tt><<title_first_word>></tt> First word in title, in lowercase.
   59 
   60     - <tt><<volume>></tt> Volume number.
   61 
   62     - <tt><<year_abbreviated>></tt> Last two digits from year.
   63 
   64     - <tt><<year_full>></tt> All digits from year.
   65 
   66 
   67     <b>Note:</b> If <tt>author</tt> is empty, <tt>editor</tt> will be
   68     considered instead. On conference proceedings or monographs this situation
   69     is usual. Similarly, if <tt>title</tt> is empty, <tt>booktitle</tt> is
   70     considered.
   71 
   72     <b>Note:</b> Only one placeholder of a given field, e. g.
   73     <tt><<author_first>></tt> or <tt><<author_all_initials>></tt>, should be
   74     used to compose the ID patterns. cb2Bib only performs one substitution per
   75     field placeholder.
   76 
   77     <b>Note:</b> cb2Bib performs a series of string manipulations, such as
   78     stripping diacritics and ligatures, aimed to provide ID values suitable for
   79     BibTeX keys and platform independent filenames. Currently only ASCII
   80     characters are considered.
   81 
   82 
   83   \section citeplaceholders Cite Command Placeholders
   84 
   85     - <tt><<citeid>></tt> The <tt>citeid</tt> placeholder replicates the
   86     pattern for each citation in the selected citation list. For example, the
   87     pattern <tt>\\citenum{<<citeid>>}</tt> expands to <tt>\\citenum{cid1}
   88     \\citenum{cid2} ... </tt>
   89 
   90     - <tt><<prefix|citeids|separator>></tt> The <tt>citeids</tt> placeholder
   91     replaces the selected citation list by prepending <tt>prefix</tt> and
   92     appending <tt>separator</tt> within the pattern. For example, the markdown
   93     pattern <tt>[<<\@|citeids|;>>]</tt> expands to <tt>[\@cid1; \@cid2;
   94     ...]</tt>, and the LaTeX pattern <tt>\\citeauthor{<<|citeids|,>>}</tt>
   95     expands to <tt>\\citeauthor{cid1, cid2, ...}</tt>.
   96 
   97 
   98     <b>Note:</b> For additional information on cite commands see
   99     \htmlonly
  100     <a href="https://en.wikibooks.org/wiki/LaTeX/Bibliography_Management" target="_blank">LaTeX Bibliography
  101   Management</a>
  102     \endhtmlonly
  103     and
  104     \htmlonly
  105     <a href="https://pandoc.org/MANUAL.html#citations" target="_blank">Pandoc User's Guide</a>.
  106     \endhtmlonly
  107 
  108 */
  109 QString idMaker::makeID(const bibReference& reference)
  110 {
  111     if (_id_pattern.isEmpty())
  112         return QString();
  113     if (_id_pattern.contains(QLatin1String("<<citeid>>")))
  114         return reference.citeidName;
  115 
  116     // Initialize fields
  117     _author = reference.anyAuthor();
  118     _journal = reference.value(QLatin1String("journal"));
  119     _pages = reference.value(QLatin1String("pages"));
  120     _title = reference.anyTitle();
  121     _volume = reference.value(QLatin1String("volume"));
  122     _year = reference.value(QLatin1String("year"));
  123 
  124     // Set cite ID
  125     QString id(_id_pattern);
  126     if (_id_pattern.contains(QLatin1String("<<author_first>>")))
  127         make_author_first(&id);
  128     else if (_id_pattern.contains(QLatin1String("<<author_first_lowercase>>")))
  129         make_author_first_lowercase(&id);
  130     else if (_id_pattern.contains(QLatin1String("<<author_all_abbreviated>>")))
  131         make_author_all_abbreviated(&id);
  132     else if (_id_pattern.contains(QLatin1String("<<author_all_initials>>")))
  133         make_author_all_initials(&id);
  134 
  135     if (_id_pattern.contains(QLatin1String("<<journal_initials>>")))
  136         make_journal_initials(&id);
  137 
  138     if (_id_pattern.contains(QLatin1String("<<pages_first>>")))
  139         make_pages_first(&id);
  140     else if (_id_pattern.contains(QLatin1String("<<ppages_first>>")))
  141         make_ppages_first(&id);
  142 
  143     if (!_title_pattern.isEmpty())
  144         if (_id_pattern.contains(_title_pattern))
  145             make_title(&id);
  146 
  147     if (_id_pattern.contains(QLatin1String("<<title_first_word>>")))
  148         make_title_first_word(&id);
  149 
  150     if (_id_pattern.contains(QLatin1String("<<volume>>")))
  151         make_volume(&id);
  152 
  153     if (_id_pattern.contains(QLatin1String("<<year_abbreviated>>")))
  154         make_year_abbreviated(&id);
  155     else if (_id_pattern.contains(QLatin1String("<<year_full>>")))
  156         make_year_full(&id);
  157 
  158     return id;
  159 }
  160 
  161 void idMaker::make_author_first(QString* id)
  162 {
  163     QRegExp rx("([-'\\s\\w]+)(?:\\sand|$)");
  164     rx.setMinimal(true);
  165     rx.indexIn(_author);
  166     _author = rx.cap(1);
  167     if (_author.contains(c2bUtils::nonAsciiLetter))
  168         _author = c2bUtils::toAscii(_author, c2bUtils::Cleanup);
  169     id->replace(QLatin1String("<<author_first>>"), _author);
  170 }
  171 
  172 void idMaker::make_author_first_lowercase(QString* id)
  173 {
  174     QRegExp rx("([-'\\s\\w]+)(?:\\sand|$)");
  175     rx.setMinimal(true);
  176     rx.indexIn(_author);
  177     _author = rx.cap(1).toLower();
  178     if (_author.contains(c2bUtils::nonAsciiLetter))
  179         _author = c2bUtils::toAscii(_author, c2bUtils::Cleanup);
  180     id->replace(QLatin1String("<<author_first_lowercase>>"), _author);
  181 }
  182 
  183 void idMaker::make_author_all_abbreviated(QString* id)
  184 {
  185     // If there is less than 3 letters in their last name's last word,
  186     // then use all the letters in the last name's last word
  187     QString temp_author;
  188     QRegExp rx("([-'\\w]{1,3})(?:[-'\\w]*)(?:\\sand|$)");
  189     rx.setMinimal(true);
  190     rx.indexIn(_author);
  191     int pos(0);
  192     while ((pos = rx.indexIn(_author, pos)) != -1)
  193     {
  194         temp_author += rx.cap(1);
  195         pos += rx.matchedLength();
  196     }
  197     _author = temp_author.toLower();
  198     if (_author.contains(c2bUtils::nonAsciiLetter))
  199         _author = c2bUtils::toAscii(_author, c2bUtils::Cleanup);
  200     id->replace(QLatin1String("<<author_all_abbreviated>>"), _author);
  201 }
  202 
  203 void idMaker::make_author_all_initials(QString* id)
  204 {
  205     _author.remove(QRegExp("\\b\\w\\b"));
  206     _author.remove(" and ");
  207     if (_author.contains(c2bUtils::nonAsciiLetter))
  208         _author = c2bUtils::toAscii(_author, c2bUtils::Cleanup);
  209     _author.remove(QRegExp("[a-z]"));
  210     id->replace(QLatin1String("<<author_all_initials>>"), _author);
  211 }
  212 
  213 void idMaker::make_journal_initials(QString* id)
  214 {
  215     _journal.remove(QRegExp("[^A-Z]"));
  216     id->replace(QLatin1String("<<journal_initials>>"), _journal);
  217 }
  218 
  219 void idMaker::make_pages_first(QString* id)
  220 {
  221     _pages = c2bUtils::firstPage(_pages);
  222     id->replace(QLatin1String("<<pages_first>>"), _pages);
  223 }
  224 
  225 void idMaker::make_ppages_first(QString* id)
  226 {
  227     _pages = c2bUtils::firstPage(_pages);
  228     if (!_pages.isEmpty())
  229         if (_pages.at(0).isDigit())
  230             _pages = 'p' + _pages;
  231     id->replace(QLatin1String("<<ppages_first>>"), _pages);
  232 }
  233 
  234 void idMaker::make_title(QString* id)
  235 {
  236     if (_title.contains(c2bUtils::nonAsciiLetter))
  237         _title = c2bUtils::toAscii(_title, c2bUtils::FromBibTeX);
  238     _title = _title.left(_title_max_length).trimmed(); // Avoid possible trailing blank
  239     if (_is_title_underscored)
  240         _title.replace(QLatin1Char(' '), QLatin1Char('_'));
  241     id->replace(_title_pattern, _title);
  242 }
  243 
  244 void idMaker::make_title_first_word(QString* id)
  245 {
  246     if (_title.contains(c2bUtils::nonAsciiLetter))
  247         _title = c2bUtils::toAscii(_title, c2bUtils::FromBibTeX);
  248     const QStringList ws(_title.toLower().split(c2bUtils::nonAsciiLetter, QString::SkipEmptyParts));
  249     _title.resize(0);
  250     for (int w = 0; w < ws.count(); ++w)
  251         if (ws.at(w).length() > 2 && ws.at(w) != QLatin1String("are") && ws.at(w) != QLatin1String("the"))
  252         {
  253             _title = ws.at(w);
  254             break;
  255         }
  256     id->replace(QLatin1String("<<title_first_word>>"), _title);
  257 }
  258 
  259 void idMaker::make_volume(QString* id)
  260 {
  261     _volume.remove(' ');
  262     id->replace(QLatin1String("<<volume>>"), _volume);
  263 }
  264 
  265 void idMaker::make_year_abbreviated(QString* id)
  266 {
  267     _year = _year.right(2);
  268     id->replace(QLatin1String("<<year_abbreviated>>"), _year);
  269 }
  270 
  271 void idMaker::make_year_full(QString* id)
  272 {
  273     id->replace(QLatin1String("<<year_full>>"), _year);
  274 }
  275 
  276 void idMaker::loadSettings()
  277 {
  278     _id_pattern = settings::instance()->value(_pattern_key).toString();
  279     QRegExp title_pattern("(<<title(?:_underscored)?(?:_\\d+)?>>)");
  280     if (title_pattern.indexIn(_id_pattern) > -1)
  281     {
  282         _title_pattern = title_pattern.cap(1);
  283         _title_pattern.remove(QRegExp("\\D"));
  284         _title_max_length = _title_pattern.toInt();
  285         if (_title_max_length == 0)
  286             _title_max_length = -1;
  287         _title_pattern = title_pattern.cap(1);
  288         _is_title_underscored = _title_pattern.contains(QRegExp("_underscored(?:_\\d+)?>>"));
  289     }
  290     else
  291         _title_pattern.clear();
  292 }