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,11 +726,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
@ -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,
string const & value, bool replace)
{
@ -748,19 +770,19 @@ void InsetListingsParams::addParam(string const & key,
// duplicate parameters!
string keyname = key;
if (!replace && 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;
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 {
@ -771,9 +793,9 @@ void InsetListingsParams::addParam(string const & key,
break;
}
if (has_special_char)
params_[keyname] = "{" + value + "}";
params_.push_back(make_pair(keyname, "{" + value + "}"));
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
{
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 = (hasParam(param)) ? getValue(param) : string();
if (prefixIs(par, "{") && suffixIs(par, "}"))
return par.substr(1, par.size() - 2);
else
@ -883,9 +904,11 @@ 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);
// 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;
}

View File

@ -83,8 +83,15 @@ private:
/// inline or normal listings
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
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
InsetCollapsable::CollapseStatus status_;