]> git.lyx.org Git - features.git/commitdiff
Allow for multiple use of same key in qualified citation lists
authorJuergen Spitzmueller <spitz@lyx.org>
Wed, 7 Aug 2019 11:00:29 +0000 (13:00 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 18 Jun 2020 13:48:42 +0000 (15:48 +0200)
File format change

Fixes: #11618, #11632
development/FORMAT
lib/lyx2lyx/lyx_2_4.py
src/BiblioInfo.cpp
src/BiblioInfo.h
src/Citation.h
src/frontends/qt/GuiCitation.cpp
src/frontends/qt/Menus.cpp
src/insets/InsetCitation.cpp
src/insets/InsetCitation.h
src/tex2lyx/text.cpp
src/version.h

index 4bf18da61e12ac0c438bd771f871d60278ccb45e..340d009e99a817056d94443ff0ef43a7ca0c7afc 100644 (file)
@@ -7,6 +7,9 @@ changes happened in particular if possible. A good example would be
 
 -----------------------
 
+2019-08-07 Jürgen Spitzmüller <spitz@lyx.org>
+       * Format incremented to 586: Allow for duplicate keys in qualified citation lists
+
 2019-08-06 Jürgen Spitzmüller <spitz@lyx.org>
        * Format incremented to 585: 
           - Add more page sizes to KOMA and memoir.
index 47311b67c7b423ef9604251e14485c0c217e7ade..3869e07b49aed388466dbab0b916d5bd8925fb15 100644 (file)
@@ -3215,6 +3215,148 @@ def revert_komafontsizes(document):
         return
     document.header[i] = document.header[i] + "," + fsize
 
+
+def revert_dupqualicites(document):
+    " Revert qualified citation list commands with duplicate keys to ERT "
+
+    # LyX 2.3 only supports qualified citation lists with unique keys. Thus,
+    # we need to revert those with multiple uses of the same key.
+
+    # Get cite engine
+    engine = "basic"
+    i = find_token(document.header, "\\cite_engine", 0)
+    if i == -1:
+        document.warning("Malformed document! Missing \\cite_engine")
+    else:
+        engine = get_value(document.header, "\\cite_engine", i)
+
+    if not engine in ["biblatex", "biblatex-natbib"]:
+        return
+
+    # Citation insets that support qualified lists, with their LaTeX code
+    ql_citations = {
+        "cite" : "cites",
+        "Cite" : "Cites",
+        "citet" : "textcites",
+        "Citet" : "Textcites",
+        "citep" : "parencites",
+        "Citep" : "Parencites",
+        "Footcite" : "Smartcites",
+        "footcite" : "smartcites",
+        "Autocite" : "Autocites",
+        "autocite" : "autocites",
+        }
+
+    i = 0
+    while (True):
+        i = find_token(document.body, "\\begin_inset CommandInset citation", i)
+        if i == -1:
+            break
+        j = find_end_of_inset(document.body, i)
+        if j == -1:
+            document.warning("Can't find end of citation inset at line %d!!" %(i))
+            i += 1
+            continue
+
+        k = find_token(document.body, "LatexCommand", i, j)
+        if k == -1:
+            document.warning("Can't find LatexCommand for citation inset at line %d!" %(i))
+            i = j + 1
+            continue
+
+        cmd = get_value(document.body, "LatexCommand", k)
+        if not cmd in list(ql_citations.keys()):
+            i = j + 1
+            continue
+
+        pres = find_token(document.body, "pretextlist", i, j)
+        posts = find_token(document.body, "posttextlist", i, j)
+        if pres == -1 and posts == -1:
+            # nothing to do.
+            i = j + 1
+            continue
+
+        key = get_quoted_value(document.body, "key", i, j)
+        if not key:
+            document.warning("Citation inset at line %d does not have a key!" %(i))
+            i = j + 1
+            continue
+
+        keys = key.split(",")
+        ukeys = list(set(keys))
+        if len(keys) == len(ukeys):
+            # no duplicates.
+            i = j + 1
+            continue
+
+        pretexts = get_quoted_value(document.body, "pretextlist", pres)
+        posttexts = get_quoted_value(document.body, "posttextlist", posts)
+
+        pre = get_quoted_value(document.body, "before", i, j)
+        post = get_quoted_value(document.body, "after", i, j)
+        prelist = pretexts.split("\t")
+        premap = dict()
+        for pp in prelist:
+            ppp = pp.split(" ", 1)
+            val = ""
+            if len(ppp) > 1:
+                val = ppp[1]
+            else:
+                val = ""
+            if ppp[0] in premap:
+                premap[ppp[0]] = premap[ppp[0]] + "\t" + val
+            else:
+                premap[ppp[0]] = val
+        postlist = posttexts.split("\t")
+        postmap = dict()
+        num = 1
+        for pp in postlist:
+            ppp = pp.split(" ", 1)
+            val = ""
+            if len(ppp) > 1:
+                val = ppp[1]
+            else:
+                val = ""
+            if ppp[0] in postmap:
+                postmap[ppp[0]] = postmap[ppp[0]] + "\t" + val
+            else:
+                postmap[ppp[0]] = val
+        # Replace known new commands with ERT
+        if "(" in pre or ")" in pre:
+            pre = "{" + pre + "}"
+        if "(" in post or ")" in post:
+            post = "{" + post + "}"
+        res = "\\" + ql_citations[cmd]
+        if pre:
+            res += "(" + pre + ")"
+        if post:
+            res += "(" + post + ")"
+        elif pre:
+            res += "()"
+        for kk in keys:
+            if premap.get(kk, "") != "":
+                akeys = premap[kk].split("\t", 1)
+                akey = akeys[0]
+                if akey != "":
+                    res += "[" + akey + "]"
+                if len(akeys) > 1:
+                    premap[kk] = "\t".join(akeys[1:])
+                else:
+                    premap[kk] = ""
+            if postmap.get(kk, "") != "":
+                akeys = postmap[kk].split("\t", 1)
+                akey = akeys[0]
+                if akey != "":
+                    res += "[" + akey + "]"
+                if len(akeys) > 1:
+                    postmap[kk] = "\t".join(akeys[1:])
+                else:
+                    postmap[kk] = ""
+            elif premap.get(kk, "") != "":
+                res += "[]"
+            res += "{" + kk + "}"
+        document.body[i:j+1] = put_cmd_in_ert([res])
+
     
 
 ##
@@ -3263,10 +3405,12 @@ convert = [
            [582, [convert_AdobeFonts,convert_latexFonts,convert_notoFonts,convert_CantarellFont,convert_FiraFont]],# old font re-converterted due to extra options
            [583, [convert_ChivoFont,convert_Semibolds,convert_NotoRegulars,convert_CrimsonProFont]],
            [584, []],
-           [585, [convert_pagesizes]]
+           [585, [convert_pagesizes]],
+           [586, []]
           ]
 
-revert =  [[584, [revert_pagesizes,revert_komafontsizes]],
+revert =  [[585, [revert_dupqualicites]],
+           [584, [revert_pagesizes,revert_komafontsizes]],
            [583, [revert_vcsinfo_rev_abbrev]],
            [582, [revert_ChivoFont,revert_CrimsonProFont]],
            [581, [revert_CantarellFont,revert_FiraFont]],
index b0f64bd0e3e7af0db0ddefc95be89dcf5fe6a378..c723b9ad398465f483b5a24d399042ffd9a0f61e 100644 (file)
@@ -488,7 +488,7 @@ docstring processRichtext(docstring const & str, bool richtext)
 //////////////////////////////////////////////////////////////////////
 
 BibTeXInfo::BibTeXInfo(docstring const & key, docstring const & type)
-       : is_bibtex_(true), bib_key_(key), entry_type_(type), info_(),
+       : is_bibtex_(true), bib_key_(key), num_bib_key_(0), entry_type_(type), info_(),
          modifier_(0)
 {}
 
@@ -1129,11 +1129,33 @@ docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf,
                        ret = ci.textBefore;
                else if (key == "textafter")
                        ret = ci.textAfter;
-               else if (key == "curpretext")
-                       ret = ci.getPretexts()[bib_key_];
-               else if (key == "curposttext")
-                       ret = ci.getPosttexts()[bib_key_];
-               else if (key == "year")
+               else if (key == "curpretext") {
+                       vector<pair<docstring, docstring>> pres = ci.getPretexts();
+                       vector<pair<docstring, docstring>>::iterator it = pres.begin();
+                       int numkey = 1;
+                       for (; it != pres.end() ; ++it) {
+                               if ((*it).first == bib_key_ && numkey == num_bib_key_) {
+                                       ret = (*it).second;
+                                       pres.erase(it);
+                                       break;
+                               }
+                               if ((*it).first == bib_key_)
+                                       ++numkey;
+                       }
+               } else if (key == "curposttext") {
+                       vector<pair<docstring, docstring>> posts = ci.getPosttexts();
+                       vector<pair<docstring, docstring>>::iterator it = posts.begin();
+                       int numkey = 1;
+                       for (; it != posts.end() ; ++it) {
+                               if ((*it).first == bib_key_ && numkey == num_bib_key_) {
+                                       ret = (*it).second;
+                                       posts.erase(it);
+                                       break;
+                               }
+                               if ((*it).first == bib_key_)
+                                       ++numkey;
+                       }
+               } else if (key == "year")
                        ret = getYear();
        }
 
@@ -1342,7 +1364,14 @@ docstring const BiblioInfo::getLabel(vector<docstring> keys,
        docstring ret = format;
        vector<docstring>::const_iterator key = keys.begin();
        vector<docstring>::const_iterator ken = keys.end();
+       vector<docstring> handled_keys;
        for (int i = 0; key != ken; ++key, ++i) {
+               handled_keys.push_back(*key);
+               int n = 0;
+               for (auto const k : handled_keys) {
+                       if (k == *key)
+                               ++n;
+               }
                BiblioInfo::const_iterator it = find(*key);
                BibTeXInfo empty_data;
                empty_data.key(*key);
@@ -1356,6 +1385,7 @@ docstring const BiblioInfo::getLabel(vector<docstring> keys,
                                        xrefptrs.push_back(&(xrefit->second));
                        }
                }
+               data.numKey(n);
                ret = data.getLabel(xrefptrs, buf, ret, ci, key + 1 != ken, i == 1);
        }
 
index 61e525d2d994bbc0a6968104b1caf48303c192de..c348a235418bfcf94a2600c8e5184e38cddabe47 100644 (file)
@@ -97,6 +97,9 @@ public:
        void label(docstring const & d) { label_= d; }
        ///
        void key(docstring const & d) { bib_key_= d; }
+       /// Record the number of occurences of the same key
+       /// (duplicates are allowed with qualified citation lists)
+       void numKey(int const i) { num_bib_key_ = i; }
        ///
        docstring const & label() const { return label_; }
        ///
@@ -145,6 +148,8 @@ private:
        bool is_bibtex_;
        /// the BibTeX key for this entry
        docstring bib_key_;
+       /// Number of occurences of the same key
+       int num_bib_key_;
        /// the label that will appear in citations
        /// this is easily set from bibliography environments, but has
        /// to be calculated for entries we get from BibTeX
index 600ba6ca97bc8a8b1282ec5606283793b71eb254..8aeb56c3e5a207b39fa67135692b836ef934716a 100644 (file)
@@ -13,8 +13,8 @@
 #define CITATION_H
 
 #include "support/docstring.h"
-#include <map>
 #include <string>
+#include <vector>
 
 namespace lyx {
 
@@ -87,14 +87,16 @@ public:
        docstring textAfter;
        /// text before the citation
        docstring textBefore;
+       ///
+       typedef std::vector<std::pair<docstring, docstring>> QualifiedList;
        /// Qualified lists's pre texts
-       std::map<docstring, docstring> pretexts;
+       QualifiedList pretexts;
        ///
-       std::map<docstring, docstring> getPretexts() const { return pretexts; }
+       QualifiedList getPretexts() const { return pretexts; }
        /// Qualified lists's post texts
-       std::map<docstring, docstring> posttexts;
+       QualifiedList posttexts;
        ///
-       std::map<docstring, docstring> getPosttexts() const { return posttexts; }
+       QualifiedList getPosttexts() const { return posttexts; }
        /// the maximum display size as a label
        size_t max_size;
        /// the maximum size of the processed keys
index 3ef4bb77f3135a4f81c8701553881720849fa821..e5610589c893492eff628e01c98e170027898324 100644 (file)
@@ -694,6 +694,8 @@ QStringList GuiCitation::selectedKeys()
 
 void GuiCitation::setPreTexts(vector<docstring> const m)
 {
+       // account for multiple use of the same keys
+       QList<QModelIndex> handled;
        for (docstring const & s: m) {
                QStandardItem * si = new QStandardItem();
                docstring key;
@@ -701,11 +703,17 @@ void GuiCitation::setPreTexts(vector<docstring> const m)
                si->setData(toqstr(pre));
                si->setText(toqstr(pre));
                QModelIndexList qmil =
-                               selected_model_.match(selected_model_.index(0, 1),
-                                                    Qt::DisplayRole, toqstr(key), 1,
-                                                    Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap));
-               if (!qmil.empty())
-                       selected_model_.setItem(qmil.front().row(), 0, si);
+                       selected_model_.match(selected_model_.index(0, 1),
+                                            Qt::DisplayRole, toqstr(key), -1,
+                                            Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap));
+               for (int i = 0; i < qmil.size(); ++i){
+                       QModelIndex idx = qmil[i];
+                       if (!handled.contains(idx)) {
+                               selected_model_.setItem(idx.row(), 0, si);
+                               handled.append(idx);
+                               break;
+                       }
+               }
        }
 }
 
@@ -716,7 +724,7 @@ vector<docstring> GuiCitation::getPreTexts()
        for (int i = 0; i != selected_model_.rowCount(); ++i) {
                QStandardItem const * key = selected_model_.item(i, 1);
                QStandardItem const * pre = selected_model_.item(i, 0);
-               if (key && pre && !key->text().isEmpty() && !pre->text().isEmpty())
+               if (key && pre && !key->text().isEmpty())
                        res.push_back(qstring_to_ucs4(key->text()) + " " + qstring_to_ucs4(pre->text()));
        }
        return res;
@@ -725,6 +733,8 @@ vector<docstring> GuiCitation::getPreTexts()
 
 void GuiCitation::setPostTexts(vector<docstring> const m)
 {
+       // account for multiple use of the same keys
+       QList<QModelIndex> handled;
        for (docstring const & s: m) {
                QStandardItem * si = new QStandardItem();
                docstring key;
@@ -732,11 +742,17 @@ void GuiCitation::setPostTexts(vector<docstring> const m)
                si->setData(toqstr(post));
                si->setText(toqstr(post));
                QModelIndexList qmil =
-                               selected_model_.match(selected_model_.index(0, 1),
-                                                    Qt::DisplayRole, toqstr(key), 1,
-                                                    Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap));
-               if (!qmil.empty())
-                       selected_model_.setItem(qmil.front().row(), 2, si);
+                       selected_model_.match(selected_model_.index(0, 1),
+                                            Qt::DisplayRole, toqstr(key), -1,
+                                            Qt::MatchFlags(Qt::MatchExactly | Qt::MatchWrap));
+               for (int i = 0; i < qmil.size(); ++i){
+                       QModelIndex idx = qmil[i];
+                       if (!handled.contains(idx)) {
+                               selected_model_.setItem(idx.row(), 2, si);
+                               handled.append(idx);
+                               break;
+                       }
+               }
        }
 }
 
@@ -747,7 +763,7 @@ vector<docstring> GuiCitation::getPostTexts()
        for (int i = 0; i != selected_model_.rowCount(); ++i) {
                QStandardItem const * key = selected_model_.item(i, 1);
                QStandardItem const * post = selected_model_.item(i, 2);
-               if (key && post && !key->text().isEmpty() && !post->text().isEmpty())
+               if (key && post && !key->text().isEmpty())
                        res.push_back(qstring_to_ucs4(key->text()) + " " + qstring_to_ucs4(post->text()));
        }
        return res;
@@ -894,17 +910,17 @@ BiblioInfo::CiteStringMap GuiCitation::citationStyles(BiblioInfo const & bi, siz
                && (selectedLV->model()->rowCount() > 1
                    || !pretexts.empty()
                    || !posttexts.empty());
-       std::map<docstring, docstring> pres;
+       vector<pair<docstring, docstring>> pres;
        for (docstring const & s: pretexts) {
                docstring key;
                docstring val = split(s, key, ' ');
-               pres[key] = val;
+               pres.push_back(make_pair(key, val));
        }
-       std::map<docstring, docstring> posts;
+       vector<pair<docstring, docstring>> posts;
        for (docstring const & s: posttexts) {
                docstring key;
                docstring val = split(s, key, ' ');
-               posts[key] = val;
+               posts.push_back(make_pair(key, val));
        }
        CiteItem ci;
        ci.textBefore = qstring_to_ucs4(textBeforeED->text());
index f8979cfa0950002e8da740707630d7d0c7d0ece8..498f53d00f79769171e535ba0c0ae32c220f4b02 100644 (file)
@@ -1609,9 +1609,9 @@ void MenuDefinition::expandCiteStyles(BufferView const * bv)
                && (keys.size() > 1
                    || !citinset->getParam("pretextlist").empty()
                    || !citinset->getParam("posttextlist").empty());
-       std::map<docstring, docstring> pres =
+       vector<pair<docstring, docstring>> pres =
                citinset->getQualifiedLists(citinset->getParam("pretextlist"));
-       std::map<docstring, docstring> posts =
+       vector<pair<docstring, docstring>> posts =
                citinset->getQualifiedLists(citinset->getParam("posttextlist"));
 
        CiteItem ci;
index 6d5c381df89c0c22a4345b6272e2082387d81773..401d0142b5cab1e410278d635b0c6b94ce839514 100644 (file)
@@ -329,15 +329,17 @@ inline docstring wrapCitation(docstring const & key,
 } // anonymous namespace
 
 
-map<docstring, docstring> InsetCitation::getQualifiedLists(docstring const p) const
+vector<pair<docstring, docstring>> InsetCitation::getQualifiedLists(docstring const p) const
 {
        vector<docstring> ps =
                getVectorFromString(p, from_ascii("\t"));
-       std::map<docstring, docstring> res;
+       QualifiedList res;
        for (docstring const & s: ps) {
-               docstring key;
-               docstring val = split(s, key, ' ');
-               res[key] = val;
+               docstring key = s;
+               docstring val;
+               if (contains(s, ' '))
+                       val = split(s, key, ' ');
+               res.push_back(make_pair(key, val));
        }
        return res;
 }
@@ -399,8 +401,8 @@ docstring InsetCitation::complexLabel(bool for_xhtml) const
                && (keys.size() > 1
                    || !getParam("pretextlist").empty()
                    || !getParam("posttextlist").empty());
-       map<docstring, docstring> pres = getQualifiedLists(getParam("pretextlist"));
-       map<docstring, docstring> posts = getQualifiedLists(getParam("posttextlist"));
+       QualifiedList pres = getQualifiedLists(getParam("pretextlist"));
+       QualifiedList posts = getQualifiedLists(getParam("posttextlist"));
 
        CiteItem ci;
        ci.textBefore = getParam("before");
@@ -611,12 +613,30 @@ void InsetCitation::latex(otexstream & os, OutputParams const & runparams) const
                os << '{' << escape(cleanupWhitespace(key)) << '}';
        else {
                if (qualified) {
-                       map<docstring, docstring> pres = getQualifiedLists(getParam("pretextlist"));
-                       map<docstring, docstring> posts = getQualifiedLists(getParam("posttextlist"));
-                       for (docstring const & k: keys) {
-                               docstring bef = params().prepareCommand(runparams, pres[k],
+                       QualifiedList pres = getQualifiedLists(getParam("pretextlist"));
+                       QualifiedList posts = getQualifiedLists(getParam("posttextlist"));
+                       for (docstring const & k : keys) {
+                               docstring prenote;
+                               QualifiedList::iterator it = pres.begin();
+                               for (; it != pres.end() ; ++it) {
+                                       if ((*it).first == k) {
+                                               prenote = (*it).second;
+                                               pres.erase(it);
+                                               break;
+                                       }
+                               }
+                               docstring bef = params().prepareCommand(runparams, prenote,
                                                   pinfo["pretextlist"].handling());
-                               docstring aft = params().prepareCommand(runparams, posts[k],
+                               docstring postnote;
+                               QualifiedList::iterator pit = posts.begin();
+                               for (; pit != posts.end() ; ++pit) {
+                                       if ((*pit).first == k) {
+                                               postnote = (*pit).second;
+                                               posts.erase(pit);
+                                               break;
+                                       }
+                               }
+                               docstring aft = params().prepareCommand(runparams, postnote,
                                                   pinfo["posttextlist"].handling());
                                if (!bef.empty())
                                        os << '[' << protectArgument(bef)
index a8e9e1853d9fc797b2715b4c41a49e093f8f527e..7c8231c538d9eca2a3e8e44f12a9db2aa228adc3 100644 (file)
@@ -82,12 +82,14 @@ public:
        static bool isCompatibleCommand(std::string const &);
        //@}
        ///
+       typedef std::vector<std::pair<docstring, docstring>> QualifiedList;
+       ///
        void redoLabel() { cache.recalculate = true; }
        ///
        CitationStyle getCitationStyle(BufferParams const & bp, std::string const & input,
                                       std::vector<CitationStyle> const & valid_styles) const;
        ///
-       std::map<docstring, docstring> getQualifiedLists(docstring const p) const;
+       QualifiedList getQualifiedLists(docstring const p) const;
        ///
        static bool last_literal;
 
index 2b34adc55e9a253db3ffb05c0ea08191041bfbbd..b66ef7f44a206f2abe6854dc75872f2b80f105cc 100644 (file)
@@ -4461,13 +4461,13 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                        }
                        string keys, pretextlist, posttextlist;
                        if (qualified) {
-                               map<string, string> pres, posts, preslit, postslit;
+                               vector<pair<string, string>> pres, posts, preslit, postslit;
                                vector<string> lkeys;
                                // text before the citation
                                string lbefore, lbeforelit;
                                // text after the citation
                                string lafter, lafterlit;
-                               string lkey;    
+                               string lkey;
                                pair<bool, string> laft, lbef;
                                while (true) {
                                        get_cite_arguments(p, true, lbefore, lafter);
@@ -4478,7 +4478,7 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                                laft = convert_latexed_command_inset_arg(lafter);
                                                literal |= !laft.first;
                                                lafter = laft.second;
-                                               lafterlit = subst(lbefore, "\n", " ");
+                                               lafterlit = subst(lafter, "\n", " ");
                                        }
                                        if (!lbefore.empty()) {
                                                lbefore.erase(0, 1);
@@ -4503,14 +4503,10 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                        lkey = p.getArg('{', '}');
                                        if (lkey.empty())
                                                break;
-                                       if (!lbefore.empty()) {
-                                               pres.insert(make_pair(lkey, lbefore));
-                                               preslit.insert(make_pair(lkey, lbeforelit));
-                                       }
-                                       if (!lafter.empty()) {
-                                               posts.insert(make_pair(lkey, lafter));
-                                               postslit.insert(make_pair(lkey, lafterlit));
-                                       }
+                                       pres.push_back(make_pair(lkey, lbefore));
+                                       preslit.push_back(make_pair(lkey, lbeforelit));
+                                       posts.push_back(make_pair(lkey, lafter));
+                                       postslit.push_back(make_pair(lkey, lafterlit));
                                        lkeys.push_back(lkey);
                                }
                                keys = convert_literate_command_inset_arg(getStringFromVector(lkeys));
@@ -4521,12 +4517,16 @@ void parse_text(Parser & p, ostream & os, unsigned flags, bool outer,
                                for (auto const & ptl : pres) {
                                        if (!pretextlist.empty())
                                                pretextlist += '\t';
-                                       pretextlist += ptl.first + " " + ptl.second;
+                                       pretextlist += ptl.first;
+                                       if (!ptl.second.empty())
+                                               pretextlist += " " + ptl.second;
                                }
                                for (auto const & potl : posts) {
                                        if (!posttextlist.empty())
                                                posttextlist += '\t';
-                                       posttextlist += potl.first + " " + potl.second;
+                                       posttextlist += potl.first;
+                                       if (!potl.second.empty())
+                                               posttextlist += " " + potl.second;
                                }
                        } else
                                keys = convert_literate_command_inset_arg(p.verbatim_item());
index 15e2e737fd2f163673a14b563e481341c9dbee25..ca5e63df4a1a58522b2496e33fc38127ffd38dfe 100644 (file)
@@ -32,8 +32,8 @@ extern char const * const lyx_version_info;
 
 // Do not remove the comment below, so we get merge conflict in
 // independent branches. Instead add your own.
-#define LYX_FORMAT_LYX 585 // spitz: add more page sizes to KOMA and memoir
-#define LYX_FORMAT_TEX2LYX 585
+#define LYX_FORMAT_LYX 586 // spitz: allow duplicate keys in qualified citation lists
+#define LYX_FORMAT_TEX2LYX 586
 
 #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
 #ifndef _MSC_VER