Use a new internal structure for InsetListingsParams, fix bugs 3713 and 3718

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18501 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Bo Peng 2007-05-24 22:19:58 +00:00
parent b28458129d
commit e5bf150a0c
4 changed files with 75 additions and 76 deletions

View File

@ -551,7 +551,7 @@ int InsetInclude::latex(Buffer const & buffer, odocstream & os,
// opt is set in QInclude dialog and should have passed validation. // opt is set in QInclude dialog and should have passed validation.
InsetListingsParams params(opt); InsetListingsParams params(opt);
if (!params.params().empty()) if (!params.params().empty())
os << "[" << from_utf8(params.encodedString()) << "]"; os << "[" << from_utf8(params.params()) << "]";
os << '{' << from_utf8(incfile) << '}'; os << '{' << from_utf8(incfile) << '}';
} else { } else {
runparams.exportdata->addExternalFile(tex_format, writefile, runparams.exportdata->addExternalFile(tex_format, writefile,

View File

@ -128,7 +128,7 @@ docstring const InsetListings::editMessage() const
int InsetListings::latex(Buffer const & buf, odocstream & os, int InsetListings::latex(Buffer const & buf, odocstream & os,
OutputParams const & runparams) const OutputParams const & runparams) const
{ {
string param_string = params().encodedString(); string param_string = params().params();
// NOTE: I use {} to quote text, which is an experimental feature // NOTE: I use {} to quote text, which is an experimental feature
// of the listings package (see page 25 of the manual) // of the listings package (see page 25 of the manual)
int lines = 0; int lines = 0;

View File

@ -20,18 +20,23 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include "support/lstrings.h" #include "support/lstrings.h"
#include "support/textutils.h"
#include "support/convert.h" #include "support/convert.h"
using std::map;
using std::vector; using std::vector;
using std::ostream; using std::ostream;
using std::string; using std::string;
using std::exception; using std::exception;
using lyx::support::bformat; using lyx::support::bformat;
using lyx::support::trim; using lyx::support::trim;
using lyx::support::subst;
using lyx::support::isStrInt; using lyx::support::isStrInt;
using lyx::support::prefixIs; using lyx::support::prefixIs;
using lyx::support::suffixIs; using lyx::support::suffixIs;
using lyx::support::getVectorFromString; using lyx::support::getVectorFromString;
using lyx::isAlphaASCII;
using lyx::isDigit;
namespace lyx namespace lyx
{ {
@ -455,13 +460,13 @@ void parValidator::validate(std::string const & par) const
InsetListingsParams::InsetListingsParams() : InsetListingsParams::InsetListingsParams() :
inline_(false), params_(), keys_(0), status_(InsetCollapsable::Open) inline_(false), params_(), status_(InsetCollapsable::Open)
{ {
} }
InsetListingsParams::InsetListingsParams(string const & par, bool in, InsetCollapsable::CollapseStatus s) InsetListingsParams::InsetListingsParams(string const & par, bool in, InsetCollapsable::CollapseStatus s)
: inline_(in), params_(), keys_(0), status_(s) : inline_(in), params_(), status_(s)
{ {
// this will activate parameter validation. // this will activate parameter validation.
fromEncodedString(par); fromEncodedString(par);
@ -491,6 +496,22 @@ void InsetListingsParams::read(Lexer & lex)
} }
string InsetListingsParams::params(string sep) const
{
string par;
for (map<string, string>::const_iterator it = params_.begin();
it != params_.end(); ++it) {
if (!par.empty())
par += sep;
if (it->second.empty())
par += it->first;
else
par += it->first + '=' + it->second;
}
return par;
}
void InsetListingsParams::addParam(string const & key, string const & value) void InsetListingsParams::addParam(string const & key, string const & value)
{ {
if (key.empty()) if (key.empty())
@ -498,25 +519,33 @@ void InsetListingsParams::addParam(string const & key, string const & value)
// exception may be thown. // exception may be thown.
parValidator(key).validate(value); parValidator(key).validate(value);
// duplicate parameters! // duplicate parameters!
if (find(keys_.begin(), keys_.end(), key) != keys_.end()) if (params_.find(key) != params_.end())
throw invalidParam(bformat(_("Parameter %1$s has already been defined"), throw invalidParam(bformat(_("Parameter %1$s has already been defined"),
from_utf8(key))); from_utf8(key)));
else // check onoff flag
keys_.push_back(key); size_t idx = 0;
if (!params_.empty()) while (listings_param_table[idx].name != key)
params_ += ','; ++idx;
if (value.empty()) BOOST_ASSERT(listings_param_table[idx].name == key);
params_ += key; // onoff parameter with value false
if (listings_param_table[idx].onoff && (value == "false" || value == "{false}"))
params_[key] = string();
// if the parameter is surrounded with {}, good
else if (prefixIs(value, "{") && suffixIs(value, "}"))
params_[key] = value;
// otherwise, check if {} is needed. Add {} to all values with
// non-ascii/number characters, just to be safe
else { else {
// check onoff flag bool has_special_char = false;
size_t idx = 0; for (size_t i = 0; i < value.size(); ++i)
while (listings_param_table[idx].name != key) if (!isAlphaASCII(value[i]) && !isDigit(value[i])) {
++idx; has_special_char = true;
BOOST_ASSERT(listings_param_table[idx].name == key); break;
if (listings_param_table[idx].onoff && value == "false") }
params_ += key; if (has_special_char)
params_[key] = "{" + value + "}";
else else
params_ += key + '=' + value; params_[key] = value;
} }
} }
@ -546,7 +575,7 @@ void InsetListingsParams::addParams(string const & par)
continue; continue;
} else if (par[i] == '{' && par[i - 1] == '=') } else if (par[i] == '{' && par[i - 1] == '=')
braces ++; braces ++;
else if (par[i] == '}' && (i == par.size() - 1 || par[i + 1] == ',')) else if (par[i] == '}' && (i == par.size() - 1 || par[i + 1] == ',' || par[i + 1] == '\n'))
braces --; braces --;
if (isValue) if (isValue)
@ -562,7 +591,6 @@ void InsetListingsParams::addParams(string const & par)
void InsetListingsParams::setParams(string const & par) void InsetListingsParams::setParams(string const & par)
{ {
params_.clear(); params_.clear();
keys_.clear();
addParams(par); addParams(par);
} }
@ -570,74 +598,49 @@ void InsetListingsParams::setParams(string const & par)
string InsetListingsParams::encodedString() const string InsetListingsParams::encodedString() const
{ {
// Encode string! // Encode string!
// FIXME: // '"' is handled differently because it will
// '"' should be handled differently because it will // terminate a lyx token.
// terminate a lyx token. Right now, it is silently ignored. string par = params();
string par; // '"' is now &quot; ==> '"' is now &amp;quot;
for (size_t i = 0; i < params_.size(); ++i) { par = subst(par, "&", "&amp;");
BOOST_ASSERT(params_[i] != '\n'); // '"' is now &amp;quot; ==> '&quot;' is now &amp;quot;
if (params_[i] != '"') par = subst(par, "\"", "&quot;");
par += params_[i];
}
return par; return par;
} }
string InsetListingsParams::separatedParams(bool keepComma) const string InsetListingsParams::separatedParams(bool keepComma) const
{ {
// , might be used as regular parameter option so if (keepComma)
// the prcess might be more complicated than what I am doing here return params(",\n");
string opt; else
int braces = 0; return params("\n");
for (size_t i = 0; i < params_.size(); ++i)
if (params_[i] == ',' && braces == 0) {
if (keepComma)
opt += ",\n";
else
opt += "\n";
} else if (params_[i] == '{' && params_[i - 1] == '=') {
braces ++;
opt += params_[i];
} else if (params_[i] == '}' && (i == params_.size() -1 || params_[i + 1] == ',')) {
braces --;
opt += params_[i];
} else
opt += params_[i];
return opt;
} }
void InsetListingsParams::fromEncodedString(string const & in) void InsetListingsParams::fromEncodedString(string const & in)
{ {
// Decode string! // Decode string! Reversal of encodedString
// Do nothing because " was silently ignored. string par = in;
setParams(in); // '&quot;' is now &amp;quot; ==> '"' is now &amp;quot;
par = subst(par, "&quot;", "\"");
// '"' is now &amp;quot; ==> '"' is now &quot;
par = subst(par, "&amp;", "&");
setParams(par);
} }
bool InsetListingsParams::isFloat() const bool InsetListingsParams::isFloat() const
{ {
return find(keys_.begin(), keys_.end(), "float") != keys_.end(); return params_.find("float") != params_.end();
} }
string InsetListingsParams::getParamValue(string const & param) const string InsetListingsParams::getParamValue(string const & param) const
{ {
// is this parameter defined? // is this parameter defined?
if (find(keys_.begin(), keys_.end(), param) == keys_.end()) map<string, string>::const_iterator it = params_.find(param);
return string(); return (it == params_.end()) ? string() : it->second;
// if so, search for it
vector<string> pars = getVectorFromString(separatedParams(), "\n");
for (vector<string>::iterator it = pars.begin(); it != pars.end(); ++it)
if (prefixIs(*it, param + "=")) {
string par = it->substr(param.size() + 1);
if (prefixIs(par, "{") && suffixIs(par, "}"))
return par.substr(1, par.size() - 2);
else
return par;
}
// if param= is not found, should be something like float, return ""
return string();
} }

View File

@ -12,7 +12,7 @@
#ifndef INSETLISTINGSPARAMS_H #ifndef INSETLISTINGSPARAMS_H
#define INSETLISTINGSPARAMS_H #define INSETLISTINGSPARAMS_H
#include <vector> #include <map>
#include <exception> #include <exception>
#include "Lexer.h" #include "Lexer.h"
#include "InsetCollapsable.h" #include "InsetCollapsable.h"
@ -35,7 +35,7 @@ public:
void read(Lexer &); void read(Lexer &);
/// valid parameter string /// valid parameter string
std::string params() const { return params_; } std::string params(std::string sep=",") const;
/// add key=value to params_ /// add key=value to params_
void addParam(std::string const & key, std::string const & value); void addParam(std::string const & key, std::string const & value);
@ -79,12 +79,8 @@ private:
/// inline or normal listings /// inline or normal listings
bool inline_; bool inline_;
/// listing parameters, this will always be a *valid* string /// key-value pairs of the parameters
/// that can be passed to listing packages. std::map<std::string, std::string> params_;
std::string params_;
/// keys defined in params_
std::vector<std::string> keys_;
/// collapsable status /// collapsable status
InsetCollapsable::CollapseStatus status_; InsetCollapsable::CollapseStatus status_;