]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetListingsParams.cpp
Do not check again and again for non existing files
[lyx.git] / src / insets / InsetListingsParams.cpp
index d9e05e6b2049ca596289366c20ac7b1222b485b6..998554c395c7f3f6e33c4798c2fb469b3b6e0c36 100644 (file)
@@ -9,39 +9,25 @@
  */
 
 #include <config.h>
+#include <algorithm>
 
 #include "InsetListingsParams.h"
 
-#include "gettext.h"
 #include "Length.h"
 #include "Lexer.h"
 
+#include "support/convert.h"
+#include "support/gettext.h"
 #include "support/lstrings.h"
 #include "support/textutils.h"
-#include "support/convert.h"
-
-#include <boost/assert.hpp>
 
 #include <sstream>
 
-using std::map;
-using std::vector;
-using std::ostream;
-using std::string;
-using std::exception;
+using namespace std;
+using namespace lyx::support;
 
 namespace lyx {
 
-using support::bformat;
-using support::trim;
-using support::rtrim;
-using support::subst;
-using support::isStrInt;
-using support::prefixIs;
-using support::suffixIs;
-using support::getVectorFromString;
-using lyx::support::contains;
-
 namespace {
 
 enum param_type {
@@ -49,8 +35,9 @@ enum param_type {
        TRUEFALSE, // accept 'true' or 'false'
        INTEGER, // accept an integer
        LENGTH,  // accept a latex length
+       SKIP,    // accept a skip or a length
        ONEOF,  // accept one of a few values
-       SUBSETOF, // accept a string composed of given characters
+       SUBSETOF // accept a string composed of given characters
 };
 
 
@@ -107,17 +94,26 @@ private:
 };
 
 
+char const * allowed_skips = "\\smallskipamount,\\medskipamount,\\bigskipamount";
+
+
 docstring ListingsParam::validate(string const & par) const
 {
        bool unclosed = false;
        string par2 = par;
        // braces are allowed
-       if (prefixIs(par, "{") && suffixIs(par, "}"))
+       if (prefixIs(par, "{") && suffixIs(par, "}") && !suffixIs(par, "\\}"))
                par2 = par.substr(1, par.size() - 2);
-       else if (prefixIs(par, "{")) {
-               par2 = par.substr(1);
-               unclosed = true;
+
+       // check for unmatched braces
+       int braces = 0;
+       for (size_t i = 0; i < par2.size(); ++i) {
+               if (par2[i] == '{' && (i == 0 || par2[i-1] != '\\'))
+                       ++braces;
+               else if (par2[i] == '}' && (i == 0 || par2[i-1] != '\\'))
+                       --braces;
        }
+       unclosed = braces != 0;
 
        switch (type_) {
 
@@ -129,7 +125,7 @@ docstring ListingsParam::validate(string const & par) const
                                return _("A value is expected.");
                }
                if (unclosed)
-                               return _("Unbalanced braces!");
+                       return _("Unbalanced braces!");
                return docstring();
 
        case TRUEFALSE:
@@ -171,6 +167,20 @@ docstring ListingsParam::validate(string const & par) const
                        return _("Unbalanced braces!");
                return docstring();
 
+       case SKIP:
+               if (par2.empty() && !onoff_) {
+                       if (!hint_.empty())
+                               return hint_;
+                       else
+                               return bformat(_("Please specify a LaTeX length expression or a skip amount (%1$s)"),
+                                              from_ascii(subst(allowed_skips, ",", ", ")));
+               }
+               if (!isValidLength(par2) && tokenPos(allowed_skips, ',', par2) == -1)
+                       return _("Not a valid LaTeX length expression or skip amount.");
+               if (unclosed)
+                       return _("Unbalanced braces!");
+               return docstring();
+
        case ONEOF: {
                if (par2.empty() && !onoff_) {
                        if (!hint_.empty())
@@ -193,7 +203,7 @@ docstring ListingsParam::validate(string const & par) const
                        lists.push_back(v);
 
                // good, find the string
-               if (std::find(lists.begin(), lists.end(), par2) != lists.end()) {
+               if (find(lists.begin(), lists.end(), par2) != lists.end()) {
                        if (unclosed)
                                return _("Unbalanced braces!");
                        return docstring();
@@ -213,7 +223,6 @@ docstring ListingsParam::validate(string const & par) const
                        return bformat(_("Try one of %1$s."), from_utf8(info_));
                else
                        return bformat(_("I guess you mean %1$s."), from_utf8(matching_names));
-               return docstring();
        }
        case SUBSETOF:
                if (par2.empty() && !onoff_) {
@@ -245,7 +254,7 @@ char const * allowed_languages =
        "[Sharp]C\nC++\n[ANSI]C++\n[GNU]C++\n[ISO]C++\n[Visual]C++\nCaml\n"
        "[light]Caml\n[Objective]Caml\nClean\nCobol\n[1974]Cobol\n[1985]Cobol\n"
        "[ibm]Cobol\nComal 80\ncommand.com\n[WinXP]command.com\nComsol\ncsh\n"
-       "Delphi\nEiffel\nElan\nEuphoria\nFortran\n[77]Fortran\n[90]Fortran\n"
+       "Delphi\nEiffel\nElan\nerlang\nEuphoria\nFortran\n[77]Fortran\n[90]Fortran\n"
        "[95]Fortran\nGCL\nGnuplot\nHaskell\nHTML\nIDL\n[CORBA]IDL\ninform\n"
        "Java\n[AspectJ]Java\nJVMIS\nksh\nLingo\nLisp\n[Auto]Lisp\nLogo\n"
        "make\n[gnu]make\nMathematica\n[1.0]Mathematica\n[3.0]Mathematica\n"
@@ -260,6 +269,31 @@ char const * allowed_languages =
        "[97]VRML\nXML\nXSLT";
 
 
+/// Return language allowed in the GUI without dialect and proper casing
+string const languageonly(string const & lang)
+{
+       string const locase = ascii_lowercase(trim(lang, "{}"));
+       string const all_languages = ascii_lowercase(allowed_languages) + "\n";
+       string language = (lang.at(0) == '[') ? locase + "\n"
+                                             : string("]") + locase + "\n";
+       size_t i = all_languages.find(language);
+       if (i == string::npos && lang.at(0) != '[') {
+               language[0] = '\n';
+               i = all_languages.find(language);
+       }
+       if (i == string::npos)
+               return lang;
+       if (all_languages.at(i) == '[')
+               i = all_languages.find(']', i);
+       if (i == string::npos)
+               return lang;
+       size_t j = all_languages.find('\n', i + 1);
+       if (j == string::npos)
+               return lang;
+       return string(allowed_languages).substr(i + 1, j - i - 1);
+}
+
+
 /// ListingsParam Validator.
 /// This class is aimed to be a singleton which is instantiated in
 /// \c InsetListingsParams::addParam().
@@ -281,7 +315,7 @@ public:
 private:
        /// key is the name of the parameter
        typedef map<string, ListingsParam> ListingsParams;
-       ListingsParams all_params_;
+       ListingsParams all_params_[2];
 };
 
 
@@ -290,349 +324,584 @@ ParValidator::ParValidator()
        docstring const empty_hint;
        docstring const style_hint = _("Use \\footnotesize, \\small, \\itshape, "
                "\\ttfamily or something like that");
-       docstring const frame_hint = _("none, leftline, topline, bottomline, lines, "
+       docstring const frame_hint_mint =
+               _("none, leftline, topline, bottomline, lines, single");
+       docstring const frame_hint_lst =
+               _("none, leftline, topline, bottomline, lines, "
                "single, shadowbox or subset of trblTRBL");
        docstring const frameround_hint = _("Enter four letters (either t = round "
                "or f = square) for top right, bottom "
                "right, bottom left and top left corner.");
-       docstring const color_hint = _("Enter something like \\color{white}");
+       docstring const color_hint_mint =
+                       _("Previously defined color name as a string");
+       docstring const color_hint_lst =
+                       _("Enter something like \\color{white}");
+
+       // Listings package
 
        /// options copied from page 26 of listings manual
        // FIXME: add default parameters ... (which is not used now)
-       all_params_["float"] =
+       all_params_[0]["float"] =
                ListingsParam("false", true, SUBSETOF, "*tbph", empty_hint);
-       all_params_["floatplacement"] =
+       all_params_[0]["floatplacement"] =
                ListingsParam("tbp", false, SUBSETOF, "tbp", empty_hint);
-       all_params_["aboveskip"] =
-               ListingsParam("\\medskipamount", false, LENGTH, "", empty_hint);
-       all_params_["belowskip"] =
-               ListingsParam("\\medskipamount", false, LENGTH, "", empty_hint);
-       all_params_["lineskip"] =
-               ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["boxpos"] =
+       all_params_[0]["aboveskip"] =
+               ListingsParam("\\medskipamount", false, SKIP, "", empty_hint);
+       all_params_[0]["belowskip"] =
+               ListingsParam("\\medskipamount", false, SKIP, "", empty_hint);
+       all_params_[0]["lineskip"] =
+               ListingsParam("", false, SKIP, "", empty_hint);
+       all_params_[0]["boxpos"] =
                ListingsParam("", false, SUBSETOF, "bct", empty_hint);
-       all_params_["print"] =
+       all_params_[0]["print"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["firstline"] =
+       all_params_[0]["firstline"] =
                ListingsParam("", false, INTEGER, "", empty_hint);
-       all_params_["lastline"] =
+       all_params_[0]["lastline"] =
                ListingsParam("", false, INTEGER, "", empty_hint);
-       all_params_["linerange"] =
+       all_params_[0]["linerange"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["showlines"] =
+       all_params_[0]["showlines"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["emptylines"] =
+       all_params_[0]["emptylines"] =
                ListingsParam("", false, ALL, "", _(
                "Expect a number with an optional * before it"));
-       all_params_["gobble"] =
+       all_params_[0]["gobble"] =
                ListingsParam("", false, INTEGER, "", empty_hint);
-       all_params_["style"] =
+       all_params_[0]["style"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["language"] =
+       all_params_[0]["language"] =
                ListingsParam("", false, ONEOF, allowed_languages, empty_hint);
-       all_params_["alsolanguage"] =
+       all_params_[0]["alsolanguage"] =
                ListingsParam("", false, ONEOF, allowed_languages, empty_hint);
-       all_params_["defaultdialect"] =
+       all_params_[0]["defaultdialect"] =
                ListingsParam("", false, ONEOF, allowed_languages, empty_hint);
-       all_params_["printpod"] =
+       all_params_[0]["printpod"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["usekeywordsintag"] =
+       all_params_[0]["usekeywordsintag"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["tagstyle"] =
+       all_params_[0]["tagstyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["markfirstintag"] =
+       all_params_[0]["markfirstintag"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["makemacrouse"] =
+       all_params_[0]["makemacrouse"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["basicstyle"] =
+       all_params_[0]["basicstyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["identifierstyle"] =
+       all_params_[0]["identifierstyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["commentstyle"] =
+       all_params_[0]["commentstyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["stringstyle"] =
+       all_params_[0]["stringstyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["keywordstyle"] =
+       all_params_[0]["keywordstyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["ndkeywordstyle"] =
+       all_params_[0]["ndkeywordstyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["classoffset"] =
+       all_params_[0]["classoffset"] =
                ListingsParam("", false, INTEGER, "", empty_hint);
-       all_params_["texcsstyle"] =
+       all_params_[0]["texcsstyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["directivestyle"] =
+       all_params_[0]["directivestyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["emph"] =
+       all_params_[0]["emph"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["moreemph"] =
+       all_params_[0]["moreemph"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deleteemph"] =
+       all_params_[0]["deleteemph"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["emphstyle"] =
+       all_params_[0]["emphstyle"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["delim"] =
+       all_params_[0]["delim"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["moredelim"] =
+       all_params_[0]["moredelim"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deletedelim"] =
+       all_params_[0]["deletedelim"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["extendedchars"] =
+       all_params_[0]["extendedchars"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["inputencoding"] =
+       all_params_[0]["inputencoding"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["upquote"] =
+       all_params_[0]["upquote"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["tabsize"] =
+       all_params_[0]["tabsize"] =
                ListingsParam("", false, INTEGER, "", empty_hint);
-       all_params_["showtabs"] =
+       all_params_[0]["showtabs"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["tab"] =
+       all_params_[0]["tab"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["showspaces"] =
+       all_params_[0]["showspaces"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["showstringspaces"] =
+       all_params_[0]["showstringspaces"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["formfeed"] =
+       all_params_[0]["formfeed"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["numbers"] =
+       all_params_[0]["numbers"] =
                ListingsParam("", false, ONEOF, "none\nleft\nright", empty_hint);
-       all_params_["stepnumber"] =
+       all_params_[0]["stepnumber"] =
                ListingsParam("", false, INTEGER, "", empty_hint);
-       all_params_["numberfirstline"] =
+       all_params_[0]["numberfirstline"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["numberstyle"] =
+       all_params_[0]["numberstyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["numbersep"] =
+       all_params_[0]["numbersep"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["numberblanklines"] =
+       all_params_[0]["numberblanklines"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["firstnumber"] =
+       all_params_[0]["firstnumber"] =
                ListingsParam("", false, ALL, "", _("auto, last or a number"));
-       all_params_["name"] =
+       all_params_[0]["name"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["thelstnumber"] =
+       all_params_[0]["thelstnumber"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["title"] =
+       all_params_[0]["title"] =
                ListingsParam("", false, ALL, "", empty_hint);
        // this option is not handled in the parameter box
-       all_params_["caption"] =
+       all_params_[0]["caption"] =
                ListingsParam("", false, ALL, "", _(
                "This parameter should not be entered here. Please use the caption "
                "edit box (when using the child document dialog) or "
                "menu Insert->Caption (when defining a listing inset)"));
        // this option is not handled in the parameter box
-       all_params_["label"] =
+       all_params_[0]["label"] =
                ListingsParam("", false, ALL, "",_(
                "This parameter should not be entered here. Please use the label "
                "edit box (when using the child document dialog) or "
                "menu Insert->Label (when defining a listing inset)"));
-       all_params_["nolol"] =
+       all_params_[0]["nolol"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["captionpos"] =
+       all_params_[0]["captionpos"] =
                ListingsParam("", false, SUBSETOF, "tb", empty_hint);
-       all_params_["abovecaptionskip"] =
-               ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["belowcaptionskip"] =
-               ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["linewidth"] =
+       all_params_[0]["abovecaptionskip"] =
+               ListingsParam("", false, SKIP, "", empty_hint);
+       all_params_[0]["belowcaptionskip"] =
+               ListingsParam("", false, SKIP, "", empty_hint);
+       all_params_[0]["linewidth"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["xleftmargin"] =
+       all_params_[0]["xleftmargin"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["xrightmargin"] =
+       all_params_[0]["xrightmargin"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["resetmargins"] =
+       all_params_[0]["resetmargins"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["breaklines"] =
+       all_params_[0]["breaklines"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["prebreak"] =
+       all_params_[0]["breakatwhitespace"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[0]["prebreak"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["postbreak"] =
+       all_params_[0]["postbreak"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["breakindent"] =
+       all_params_[0]["breakindent"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["breakautoindent"] =
+       all_params_[0]["breakautoindent"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["frame"] =
-               ListingsParam("", false, ALL, "", frame_hint);
-       all_params_["frameround"] =
+       all_params_[0]["frame"] =
+               ListingsParam("", false, ALL, "", frame_hint_lst);
+       all_params_[0]["frameround"] =
                ListingsParam("", false, SUBSETOF, "tf", frameround_hint);
-       all_params_["framesep"] =
+       all_params_[0]["framesep"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["rulesep"] =
+       all_params_[0]["rulesep"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["framerule"] =
+       all_params_[0]["framerule"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["framexleftmargin"] =
+       all_params_[0]["framexleftmargin"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["framexrightmargin"] =
+       all_params_[0]["framexrightmargin"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["framextopmargin"] =
+       all_params_[0]["framextopmargin"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["framexbottommargin"] =
+       all_params_[0]["framexbottommargin"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["backgroundcolor"] =
-               ListingsParam("", false, ALL, "", color_hint );
-       all_params_["rulecolor"] =
-               ListingsParam("", false, ALL, "", color_hint );
-       all_params_["fillcolor"] =
-               ListingsParam("", false, ALL, "", color_hint );
-       all_params_["rulesepcolor"] =
-               ListingsParam("", false, ALL, "", color_hint );
-       all_params_["frameshape"] =
+       all_params_[0]["backgroundcolor"] =
+               ListingsParam("", false, ALL, "", color_hint_lst);
+       all_params_[0]["rulecolor"] =
+               ListingsParam("", false, ALL, "", color_hint_lst);
+       all_params_[0]["fillcolor"] =
+               ListingsParam("", false, ALL, "", color_hint_lst);
+       all_params_[0]["rulesepcolor"] =
+               ListingsParam("", false, ALL, "", color_hint_lst);
+       all_params_[0]["frameshape"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["index"] =
+       all_params_[0]["index"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["moreindex"] =
+       all_params_[0]["moreindex"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deleteindex"] =
+       all_params_[0]["deleteindex"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["indexstyle"] =
+       all_params_[0]["indexstyle"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["columns"] =
+       all_params_[0]["columns"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["flexiblecolumns"] =
+       all_params_[0]["flexiblecolumns"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["keepspaces"] =
+       all_params_[0]["keepspaces"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["basewidth"] =
+       all_params_[0]["basewidth"] =
                ListingsParam("", false, LENGTH, "", empty_hint);
-       all_params_["fontadjust"] =
+       all_params_[0]["fontadjust"] =
                ListingsParam("", true, TRUEFALSE, "", empty_hint);
-       all_params_["texcl"] =
+       all_params_[0]["texcl"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["mathescape"] =
+       all_params_[0]["mathescape"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["escapechar"] =
-               ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["escapeinside"] =
+       all_params_[0]["escapechar"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["escepeinside"] =
+       all_params_[0]["escapeinside"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["escepebegin"] =
+       all_params_[0]["escapebegin"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["escepeend"] =
+       all_params_[0]["escapeend"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["fancyvrb"] =
+       all_params_[0]["fancyvrb"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["fvcmdparams"] =
+       all_params_[0]["fvcmdparams"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["morefvcmdparams"] =
+       all_params_[0]["morefvcmdparams"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["keywordsprefix"] =
+       all_params_[0]["keywordsprefix"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["keywords"] =
+       all_params_[0]["keywords"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["morekeywords"] =
+       all_params_[0]["morekeywords"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deletekeywords"] =
+       all_params_[0]["deletekeywords"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["ndkeywords"] =
+       all_params_[0]["ndkeywords"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["morendkeywords"] =
+       all_params_[0]["morendkeywords"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deletendkeywords"] =
+       all_params_[0]["deletendkeywords"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["texcs"] =
+       all_params_[0]["texcs"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["moretexcs"] =
+       all_params_[0]["moretexcs"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deletetexcs"] =
+       all_params_[0]["deletetexcs"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["directives"] =
+       all_params_[0]["directives"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["moredirectives"] =
+       all_params_[0]["moredirectives"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deletedirectives"] =
+       all_params_[0]["deletedirectives"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["sensitive"] =
+       all_params_[0]["sensitive"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["alsoletter"] =
+       all_params_[0]["alsoletter"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["alsodigit"] =
+       all_params_[0]["alsodigit"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["alsoother"] =
+       all_params_[0]["alsoother"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["otherkeywords"] =
+       all_params_[0]["otherkeywords"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["tag"] =
+       all_params_[0]["tag"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["string"] =
+       all_params_[0]["string"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["morestring"] =
+       all_params_[0]["morestring"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deletestring"] =
+       all_params_[0]["deletestring"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["comment"] =
+       all_params_[0]["comment"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["morecomment"] =
+       all_params_[0]["morecomment"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deletecomment"] =
+       all_params_[0]["deletecomment"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["keywordcomment"] =
+       all_params_[0]["keywordcomment"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["morekeywordcomment"] =
+       all_params_[0]["morekeywordcomment"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deletekeywordcomment"] =
+       all_params_[0]["deletekeywordcomment"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["keywordcommentsemicolon"] =
+       all_params_[0]["keywordcommentsemicolon"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["podcomment"] =
+       all_params_[0]["podcomment"] =
                ListingsParam("", false, ALL, "", empty_hint);
        // the following are experimental listings features
-       all_params_["procnamekeys"] =
+       all_params_[0]["procnamekeys"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["moreprocnamekeys"] =
+       all_params_[0]["moreprocnamekeys"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deleteprocnamekeys"] =
+       all_params_[0]["deleteprocnamekeys"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["procnamestyle"] =
+       all_params_[0]["procnamestyle"] =
                ListingsParam("", false, ALL, "", style_hint);
-       all_params_["indexprocnames"] =
+       all_params_[0]["indexprocnames"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["hyperref"] =
+       all_params_[0]["hyperref"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["morehyperref"] =
+       all_params_[0]["morehyperref"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["deletehyperref"] =
+       all_params_[0]["deletehyperref"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["hyperanchor"] =
+       all_params_[0]["hyperanchor"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["hyperlink"] =
+       all_params_[0]["hyperlink"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["literate"] =
+       all_params_[0]["literate"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["lgrindef"] =
+       all_params_[0]["lgrindef"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["rangebeginprefix"] =
+       all_params_[0]["rangebeginprefix"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["rangebeginsuffix"] =
+       all_params_[0]["rangebeginsuffix"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["rangeendprefix"] =
+       all_params_[0]["rangeendprefix"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["rangeendsuffix"] =
+       all_params_[0]["rangeendsuffix"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["rangeprefix"] =
+       all_params_[0]["rangeprefix"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["rangesuffix"] =
+       all_params_[0]["rangesuffix"] =
                ListingsParam("", false, ALL, "", empty_hint);
-       all_params_["includerangemarker"] =
+       all_params_[0]["includerangemarker"] =
                ListingsParam("", false, TRUEFALSE, "", empty_hint);
-       all_params_["multicols"] =
+       all_params_[0]["multicols"] =
                ListingsParam("", false, INTEGER, "", empty_hint);
+
+       // Minted package
+
+       // This is not a real minted option and its only purpose
+       // is to get a caption for a floating listing.
+       all_params_[1]["caption"] =
+               ListingsParam("", false, ALL, "", _(
+               "This parameter should not be entered here. Please use the caption "
+               "edit box (when using the child document dialog) or "
+               "menu Insert->Caption (when defining a listing inset)"));
+       // The "label" minted option is being subverted here for the
+       // sake of getting a label for a floating listing.
+       all_params_[1]["label"] =
+               ListingsParam("", false, ALL, "",_(
+               "This parameter should not be entered here. Please use the label "
+               "edit box (when using the child document dialog) or "
+               "menu Insert->Label (when defining a listing inset)"));
+       // This is not a real minted option and its only purpose
+       // is to signal that this is a floating listing.
+       all_params_[1]["float"] =
+               ListingsParam("false", true, SUBSETOF, "*tbph", empty_hint);
+       all_params_[1]["cache"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["cachedir"] =
+               ListingsParam("", false, ALL, "", _(
+                                       "default: _minted-<jobname>"));
+       all_params_[1]["finalizecache"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["frozencache"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["draft"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["final"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["kpsewhich"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["langlinenos"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["newfloat"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["outputdir"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["autogobble"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["baselinestretch"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breakafter"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breakaftergroup"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["breakaftersymbolpre"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breakaftersymbolpost"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breakanywhere"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["breakanywheresymbolpre"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breakanywheresymbolpost"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breakautoindent"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["breakbefore"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breakbeforegroup"] =
+               ListingsParam("", true, ALL, "", empty_hint);
+       all_params_[1]["breakbeforesymbolpre"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breakbeforesymbolpost"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breakbytoken"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["breakbytokenanywhere"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["breakindent"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["breaklines"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["breaksymbol"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breaksymbolleft"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breaksymbolright"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["breaksymbolindent"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["breaksymbolindentleft"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["breaksymbolindentright"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["breaksymbolsep"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["breaksymbolsepleft"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["breaksymbolsepright"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["bgcolor"] =
+               ListingsParam("", false, ALL, "", color_hint_mint);
+       all_params_[1]["codetagify"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["curlyquotes"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["encoding"] =
+               ListingsParam("", false, ALL, "", _(
+                               "Sets encoding expected by Pygments"));
+       all_params_[1]["escapeinside"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["firstline"] =
+               ListingsParam("", false, INTEGER, "", empty_hint);
+       all_params_[1]["firstnumber"] =
+               ListingsParam("", false, ALL, "", _(
+                                       "auto, last or a number"));
+       all_params_[1]["fontfamily"] =
+               ListingsParam("", false, ALL, "", _(
+                               "A latex family such as tt, sf, rm"));
+       all_params_[1]["fontseries"] =
+               ListingsParam("", false, ALL, "", _(
+                               "A latex series such as m, b, c, bx, sb"));
+       all_params_[1]["fontsize"] =
+               ListingsParam("", false, ALL, "", _(
+                               "A latex name such as \\small"));
+       all_params_[1]["fontshape"] =
+               ListingsParam("", false, ALL, "", _(
+                               "A latex shape such as n, it, sl, sc"));
+       all_params_[1]["formatcom"] =
+               ListingsParam("", false, ALL, "", empty_hint);
+       all_params_[1]["frame"] =
+               ListingsParam("", false, ONEOF,
+                 "none\nleftline\ntopline\nbottomline\nlines\nsingle",
+                 frame_hint_mint);
+       all_params_[1]["framerule"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["framesep"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["funcnamehighlighting"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["gobble"] =
+               ListingsParam("", false, INTEGER, "", empty_hint);
+       all_params_[1]["highlightcolor"] =
+               ListingsParam("", false, ALL, "", color_hint_mint);
+       all_params_[1]["highlightlines"] =
+               ListingsParam("", false, ALL, "", _(
+                               "A range of lines such as {1,3-4}"));
+       all_params_[1]["keywordcase"] =
+               ListingsParam("", false, ONEOF,
+                               "lower\nupper\ncapitalize", empty_hint);
+       all_params_[1]["labelposition"] =
+               ListingsParam("", false, ONEOF,
+                       "none\ntopline\nbottomline\nall", empty_hint);
+       all_params_[1]["language"] =
+               ListingsParam("", false, ALL, "", _(
+               "Enter one of the supported languages. However, if you "
+               "are defining a listing inset, it is better using the  "
+               "language combo box, unless you need to enter a language not "
+               "offered there, otherwise the combo box will be disabled."));
+       all_params_[1]["lastline"] =
+               ListingsParam("", false, INTEGER, "", empty_hint);
+       all_params_[1]["linenos"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["numberfirstline"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["numbers"] =
+               ListingsParam("", false, ONEOF,
+                               "left\nright\nboth\nnone", empty_hint);
+       all_params_[1]["mathescape"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["numberblanklines"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["numbersep"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["obeytabs"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["outencoding"] =
+               ListingsParam("", false, ALL, "", _(
+                 "File encoding used by Pygments for highlighting"));
+       all_params_[1]["python3"] =
+               ListingsParam("", false, TRUEFALSE, "", _(
+                                       "Apply Python 3 highlighting"));
+       all_params_[1]["resetmargins"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["rulecolor"] =
+               ListingsParam("", false, ALL, "", color_hint_mint);
+       all_params_[1]["samepage"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["showspaces"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["showtabs"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["space"] =
+               ListingsParam("", false, ALL, "", _(
+                               "A macro. Default: \\textvisiblespace"));
+       all_params_[1]["spacecolor"] =
+               ListingsParam("", false, ALL, "", color_hint_mint);
+       all_params_[1]["startinline"] =
+               ListingsParam("", false, TRUEFALSE, "", _("For PHP only"));
+       all_params_[1]["style"] =
+               ListingsParam("", false, ALL, "", _(
+                                       "The style used by Pygments"));
+       all_params_[1]["stepnumber"] =
+               ListingsParam("", false, INTEGER, "", empty_hint);
+       all_params_[1]["stepnumberfromfirst"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["stepnumberoffsetvalues"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["stripall"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["stripnl"] =
+               ListingsParam("", false, TRUEFALSE, "", empty_hint);
+       all_params_[1]["tab"] =
+               ListingsParam("", false, ALL, "", _(
+                               "A macro to redefine visible tabs"));
+       all_params_[1]["tabcolor"] =
+               ListingsParam("", false, ALL, "", color_hint_mint);
+       all_params_[1]["tabsize"] =
+               ListingsParam("", false, INTEGER, "", empty_hint);
+       all_params_[1]["texcl"] =
+               ListingsParam("", false, TRUEFALSE, "", _(
+                               "Enables latex code in comments"));
+       all_params_[1]["texcomments"] =
+               ListingsParam("", false, TRUEFALSE, "", _(
+                               "Enables latex code in comments"));
+       all_params_[1]["xleftmargin"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
+       all_params_[1]["xrightmargin"] =
+               ListingsParam("", false, LENGTH, "", empty_hint);
 }
 
 
 docstring ParValidator::validate(string const & name,
                string const & par) const
 {
+       int p = InsetListingsParams::package();
+
        if (name.empty())
                return _("Invalid (empty) listing parameter name.");
 
        if (name[0] == '?') {
                string suffix = trim(string(name, 1));
                string param_names;
-               ListingsParams::const_iterator it = all_params_.begin();
-               ListingsParams::const_iterator end = all_params_.end();
+               ListingsParams::const_iterator it = all_params_[p].begin();
+               ListingsParams::const_iterator end = all_params_[p].end();
                for (; it != end; ++it) {
                        if (suffix.empty() || contains(it->first, suffix)) {
                                if (!param_names.empty())
@@ -645,13 +914,13 @@ docstring ParValidator::validate(string const & name,
                                        _("Available listing parameters are %1$s"), from_ascii(param_names));
                else
                        return bformat(
-                                       _("Available listings parameters containing string \"%1$s\" are %2$s"), 
+                                       _("Available listings parameters containing string \"%1$s\" are %2$s"),
                                                from_utf8(suffix), from_utf8(param_names));
        }
+
        // locate name in parameter table
-       ListingsParams::const_iterator it = all_params_.find(name);
-       if (it != all_params_.end()) {
+       ListingsParams::const_iterator it = all_params_[p].find(name);
+       if (it != all_params_[p].end()) {
                docstring msg = it->second.validate(par);
                if (msg.empty())
                        return msg;
@@ -660,8 +929,8 @@ docstring ParValidator::validate(string const & name,
        } else {
                // otherwise, produce a meaningful error message.
                string matching_names;
-               ListingsParams::const_iterator end = all_params_.end();
-               for (it = all_params_.begin(); it != end; ++it) {
+               ListingsParams::const_iterator end = all_params_[p].end();
+               for (it = all_params_[p].begin(); it != end; ++it) {
                        if (prefixIs(it->first, name)) {
                                if (!matching_names.empty())
                                        matching_names += ", ";
@@ -675,33 +944,38 @@ docstring ParValidator::validate(string const & name,
                        return bformat(_("Parameters starting with '%1$s': %2$s"),
                                                                from_utf8(name), from_utf8(matching_names));
        }
-       return docstring();
 }
 
 
 bool ParValidator::onoff(string const & name) const
 {
+       int p = InsetListingsParams::package();
+
        // locate name in parameter table
-       ListingsParams::const_iterator it = all_params_.find(name);
-       if (it != all_params_.end())
+       ListingsParams::const_iterator it = all_params_[p].find(name);
+       if (it != all_params_[p].end())
                return it->second.onoff_;
        else
                return false;
 }
 
-} // namespace anon.
+} // namespace
 
 // define a global ParValidator
-ParValidator * par_validator = NULL;
+ParValidator * par_validator = 0;
+
+// The package to be used by the global ParValidator
+// (0 for listings, 1 for minted)
+int InsetListingsParams::package_ = 0;
 
 InsetListingsParams::InsetListingsParams()
-       : inline_(false), params_(), status_(InsetCollapsable::Open)
+       : inline_(false), params_(), status_(InsetCollapsible::Open)
 {
 }
 
 
 InsetListingsParams::InsetListingsParams(string const & par, bool in,
-               InsetCollapsable::CollapseStatus s)
+               InsetCollapsible::CollapseStatus s)
        : inline_(in), params_(), status_(s)
 {
        // this will activate parameter validation.
@@ -722,10 +996,9 @@ void InsetListingsParams::write(ostream & os) const
 void InsetListingsParams::read(Lexer & lex)
 {
        lex >> inline_;
-       int s;
+       int s = InsetCollapsible::Collapsed;
        lex >> s;
-       if (lex)
-               status_ = static_cast<InsetCollapsable::CollapseStatus>(s);
+       status_ = static_cast<InsetCollapsible::CollapseStatus>(s);
        string par;
        lex >> par;
        fromEncodedString(par);
@@ -735,11 +1008,11 @@ void InsetListingsParams::read(Lexer & lex)
 string InsetListingsParams::params(string const & sep) const
 {
        string par;
-       for (map<string, string>::const_iterator it = params_.begin();
-               it != params_.end(); ++it) {
+       keyValuePair::const_iterator it = params_.begin();
+       for (; it != params_.end(); ++it) {
                if (!par.empty())
                        par += sep;
-               // key=value,key=value1 is stored in params_ as key=value,key_=value1. 
+               // key=value,key=value1 is stored in params_ as key=value,key_=value1.
                if (it->second.empty())
                        par += rtrim(it->first, "_");
                else
@@ -749,39 +1022,65 @@ string InsetListingsParams::params(string const & sep) const
 }
 
 
-void InsetListingsParams::addParam(string const & key, string const & value)
+bool InsetListingsParams::hasParam(string const & key) const
+{
+       keyValuePair::const_iterator it = params_.begin();
+       for (; it != params_.end(); ++it) {
+               if (it->first == key)
+                       return true;
+       }
+       return false;
+}
+
+
+string InsetListingsParams::getValue(string const & key) const
+{
+       keyValuePair::const_iterator it = params_.begin();
+       for (; it != params_.end(); ++it) {
+               if (it->first == key)
+                       return it->second;
+       }
+       return string();
+}
+
+
+void InsetListingsParams::addParam(string const & key,
+               string const & val, bool replace)
 {
        if (key.empty())
                return;
 
+       bool const is_minted_language = minted() && key == "language";
+       string const value = (is_minted_language && !val.empty())
+                               ? languageonly(val) : val;
        // duplicate parameters!
        string keyname = key;
-       if (params_.find(key) != params_.end())
+       if (!replace && hasParam(key))
                // key=value,key=value1 is allowed in listings
                // use key_, key__, key___ etc to avoid name conflict
-               while (params_.find(keyname += '_') != params_.end()) { }
+               while (hasParam(keyname += '_')) { }
        // check onoff flag
        // onoff parameter with value false
        if (!par_validator)
-               par_validator = new ParValidator();
+               par_validator = new ParValidator;
        if (par_validator->onoff(key) && (value == "false" || value == "{false}"))
-               params_[keyname] = string();
+               params_.push_back(make_pair(keyname, string()));
        // if the parameter is surrounded with {}, good
        else if (prefixIs(value, "{") && suffixIs(value, "}"))
-               params_[keyname] = value;
+               params_.push_back(make_pair(keyname, value));
        // otherwise, check if {} is needed. Add {} to all values with
        // non-ascii/number characters, just to be safe
        else {
                bool has_special_char = false;
                for (size_t i = 0; i < value.size(); ++i)
-                       if (!isAlphaASCII(value[i]) && !isDigit(value[i])) {
+                       if (!isAlnumASCII(value[i])) {
                                has_special_char = true;
                                break;
                        }
-               if (has_special_char)
-                       params_[keyname] = "{" + value + "}";
+               if (has_special_char && !is_minted_language)
+                       params_.push_back(make_pair(keyname, "{" + value + "}"));
                else
-                       params_[keyname] = value;
+                       params_.push_back(make_pair(keyname, value));
        }
 }
 
@@ -809,11 +1108,12 @@ void InsetListingsParams::addParams(string const & par)
                } else if (par[i] == '=' && braces == 0) {
                        isValue = true;
                        continue;
-               } else if (par[i] == '{' && par[i - 1] == '=')
-                       braces ++;
-               else if (par[i] == '}'
-                       && (i == par.size() - 1 || par[i + 1] == ',' || par[i + 1] == '\n'))
-                       braces --;
+               } else if (par[i] == '{' && i > 0 && par[i-1] != '\\')
+                       // don't count a brace in first position
+                       ++braces;
+               else if (par[i] == '}' && i != par.size() - 1
+                        && (i == 0 || (i > 0 && par[i-1] != '\\')))
+                       --braces;
 
                if (isValue)
                        value += par[i];
@@ -869,15 +1169,13 @@ void InsetListingsParams::fromEncodedString(string const & in)
 
 bool InsetListingsParams::isFloat() const
 {
-       return params_.find("float") != params_.end();
+       return hasParam("float");
 }
 
 
 string InsetListingsParams::getParamValue(string const & param) const
 {
-       // is this parameter defined?
-       map<string, string>::const_iterator it = params_.find(param);
-       string par = (it == params_.end()) ? string() : it->second;
+       string par = getValue(param);
        if (prefixIs(par, "{") && suffixIs(par, "}"))
                return par.substr(1, par.size() - 2);
        else
@@ -889,10 +1187,12 @@ docstring InsetListingsParams::validate() const
 {
        docstring msg;
        if (!par_validator)
-               par_validator = new ParValidator();
-       for (map<string, string>::const_iterator it = params_.begin();
-               it != params_.end(); ++it) {
-               msg = par_validator->validate(it->first, it->second);
+               par_validator = new ParValidator;
+       // return msg for first key=value pair which is incomplete or has an error
+       keyValuePair::const_iterator it = params_.begin();
+       for (; it != params_.end(); ++it) {
+               // key trimmed
+               msg = par_validator->validate(rtrim(it->first, "_"), it->second);
                if (!msg.empty())
                        return msg;
        }