Store InsetListingsParams in a vector of pairs, not a map, since order of insertion matters.

Fixes: #8144, #5203.
This commit is contained in:
Juergen Spitzmueller 2014-05-06 20:22:25 +02:00
parent e43e4456ea
commit ef05f7cca9
2 changed files with 46 additions and 16 deletions

View File

@ -726,8 +726,8 @@ void InsetListingsParams::read(Lexer & lex)
string InsetListingsParams::params(string const & sep) const string InsetListingsParams::params(string const & sep) const
{ {
string par; string par;
for (map<string, string>::const_iterator it = params_.begin(); keyValuePair::const_iterator it = params_.begin();
it != params_.end(); ++it) { for (; it != params_.end(); ++it) {
if (!par.empty()) if (!par.empty())
par += sep; 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.
@ -740,6 +740,28 @@ string InsetListingsParams::params(string const & sep) const
} }
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, void InsetListingsParams::addParam(string const & key,
string const & value, bool replace) string const & value, bool replace)
{ {
@ -748,19 +770,19 @@ void InsetListingsParams::addParam(string const & key,
// duplicate parameters! // duplicate parameters!
string keyname = key; string keyname = key;
if (!replace && params_.find(key) != params_.end()) if (!replace && hasParam(key))
// key=value,key=value1 is allowed in listings // key=value,key=value1 is allowed in listings
// use key_, key__, key___ etc to avoid name conflict // use key_, key__, key___ etc to avoid name conflict
while (params_.find(keyname += '_') != params_.end()) { } while (hasParam(keyname += '_')) { }
// check onoff flag // check onoff flag
// onoff parameter with value false // onoff parameter with value false
if (!par_validator) if (!par_validator)
par_validator = new ParValidator; par_validator = new ParValidator;
if (par_validator->onoff(key) && (value == "false" || value == "{false}")) 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 // if the parameter is surrounded with {}, good
else if (prefixIs(value, "{") && suffixIs(value, "}")) 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 // otherwise, check if {} is needed. Add {} to all values with
// non-ascii/number characters, just to be safe // non-ascii/number characters, just to be safe
else { else {
@ -771,9 +793,9 @@ void InsetListingsParams::addParam(string const & key,
break; break;
} }
if (has_special_char) if (has_special_char)
params_[keyname] = "{" + value + "}"; params_.push_back(make_pair(keyname, "{" + value + "}"));
else else
params_[keyname] = value; params_.push_back(make_pair(keyname, value));
} }
} }
@ -862,15 +884,14 @@ void InsetListingsParams::fromEncodedString(string const & in)
bool InsetListingsParams::isFloat() const bool InsetListingsParams::isFloat() const
{ {
return params_.find("float") != params_.end(); return hasParam("float");
} }
string InsetListingsParams::getParamValue(string const & param) const string InsetListingsParams::getParamValue(string const & param) const
{ {
// is this parameter defined? // is this parameter defined?
map<string, string>::const_iterator it = params_.find(param); string par = (hasParam(param)) ? getValue(param) : string();
string par = (it == params_.end()) ? string() : it->second;
if (prefixIs(par, "{") && suffixIs(par, "}")) if (prefixIs(par, "{") && suffixIs(par, "}"))
return par.substr(1, par.size() - 2); return par.substr(1, par.size() - 2);
else else
@ -883,9 +904,11 @@ docstring InsetListingsParams::validate() const
docstring msg; docstring msg;
if (!par_validator) if (!par_validator)
par_validator = new ParValidator; par_validator = new ParValidator;
for (map<string, string>::const_iterator it = params_.begin(); // return msg for first key=value pair which is incomplete or has an error
it != params_.end(); ++it) { keyValuePair::const_iterator it = params_.begin();
msg = par_validator->validate(it->first, it->second); for (; it != params_.end(); ++it) {
// key trimmed
msg = par_validator->validate(rtrim(it->first, "_"), it->second);
if (!msg.empty()) if (!msg.empty())
return msg; return msg;
} }

View File

@ -83,8 +83,15 @@ private:
/// inline or normal listings /// inline or normal listings
bool inline_; bool inline_;
/// Do we have a param with the given \c key?
bool hasParam(std::string const & key) const;
/// return the value for the given \c key, if avaible, else empty string
std::string getValue(std::string const & key) const;
/// key-value pairs of the parameters /// key-value pairs of the parameters
std::map<std::string, std::string> params_; // Use a vector of pairs in order to maintain the order of insertion.
typedef std::vector<std::pair<std::string, std::string> > keyValuePair;
keyValuePair params_;
/// collapsable status /// collapsable status
InsetCollapsable::CollapseStatus status_; InsetCollapsable::CollapseStatus status_;