From e5bf150a0c62f86ea9295462b65bd14af4764dd1 Mon Sep 17 00:00:00 2001 From: Bo Peng Date: Thu, 24 May 2007 22:19:58 +0000 Subject: [PATCH] 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 --- src/insets/InsetInclude.cpp | 2 +- src/insets/InsetListings.cpp | 2 +- src/insets/InsetListingsParams.cpp | 135 +++++++++++++++-------------- src/insets/InsetListingsParams.h | 12 +-- 4 files changed, 75 insertions(+), 76 deletions(-) diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index dd9b61637c..a9d0391a73 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -551,7 +551,7 @@ int InsetInclude::latex(Buffer const & buffer, odocstream & os, // opt is set in QInclude dialog and should have passed validation. InsetListingsParams params(opt); if (!params.params().empty()) - os << "[" << from_utf8(params.encodedString()) << "]"; + os << "[" << from_utf8(params.params()) << "]"; os << '{' << from_utf8(incfile) << '}'; } else { runparams.exportdata->addExternalFile(tex_format, writefile, diff --git a/src/insets/InsetListings.cpp b/src/insets/InsetListings.cpp index 3e5100b89e..526df7954b 100644 --- a/src/insets/InsetListings.cpp +++ b/src/insets/InsetListings.cpp @@ -128,7 +128,7 @@ docstring const InsetListings::editMessage() const int InsetListings::latex(Buffer const & buf, odocstream & os, 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 // of the listings package (see page 25 of the manual) int lines = 0; diff --git a/src/insets/InsetListingsParams.cpp b/src/insets/InsetListingsParams.cpp index 424fdcf4f5..b3171e497e 100644 --- a/src/insets/InsetListingsParams.cpp +++ b/src/insets/InsetListingsParams.cpp @@ -20,18 +20,23 @@ #include #include "support/lstrings.h" +#include "support/textutils.h" #include "support/convert.h" +using std::map; using std::vector; using std::ostream; using std::string; using std::exception; using lyx::support::bformat; using lyx::support::trim; +using lyx::support::subst; using lyx::support::isStrInt; using lyx::support::prefixIs; using lyx::support::suffixIs; using lyx::support::getVectorFromString; +using lyx::isAlphaASCII; +using lyx::isDigit; namespace lyx { @@ -455,13 +460,13 @@ void parValidator::validate(std::string const & par) const 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) - : inline_(in), params_(), keys_(0), status_(s) + : inline_(in), params_(), status_(s) { // this will activate parameter validation. fromEncodedString(par); @@ -491,6 +496,22 @@ void InsetListingsParams::read(Lexer & lex) } +string InsetListingsParams::params(string sep) const +{ + string par; + for (map::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) { if (key.empty()) @@ -498,25 +519,33 @@ void InsetListingsParams::addParam(string const & key, string const & value) // exception may be thown. parValidator(key).validate(value); // 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"), from_utf8(key))); - else - keys_.push_back(key); - if (!params_.empty()) - params_ += ','; - if (value.empty()) - params_ += key; + // check onoff flag + size_t idx = 0; + while (listings_param_table[idx].name != key) + ++idx; + BOOST_ASSERT(listings_param_table[idx].name == 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 { - // check onoff flag - size_t idx = 0; - while (listings_param_table[idx].name != key) - ++idx; - BOOST_ASSERT(listings_param_table[idx].name == key); - if (listings_param_table[idx].onoff && value == "false") - params_ += key; + bool has_special_char = false; + for (size_t i = 0; i < value.size(); ++i) + if (!isAlphaASCII(value[i]) && !isDigit(value[i])) { + has_special_char = true; + break; + } + if (has_special_char) + params_[key] = "{" + value + "}"; else - params_ += key + '=' + value; + params_[key] = value; } } @@ -546,7 +575,7 @@ void InsetListingsParams::addParams(string const & par) continue; } else if (par[i] == '{' && par[i - 1] == '=') 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 --; if (isValue) @@ -562,7 +591,6 @@ void InsetListingsParams::addParams(string const & par) void InsetListingsParams::setParams(string const & par) { params_.clear(); - keys_.clear(); addParams(par); } @@ -570,74 +598,49 @@ void InsetListingsParams::setParams(string const & par) string InsetListingsParams::encodedString() const { // Encode string! - // FIXME: - // '"' should be handled differently because it will - // terminate a lyx token. Right now, it is silently ignored. - string par; - for (size_t i = 0; i < params_.size(); ++i) { - BOOST_ASSERT(params_[i] != '\n'); - if (params_[i] != '"') - par += params_[i]; - } - return par; + // '"' is handled differently because it will + // terminate a lyx token. + string par = params(); + // '"' is now " ==> '"' is now &quot; + par = subst(par, "&", "&"); + // '"' is now &quot; ==> '"' is now &quot; + par = subst(par, "\"", """); + return par; } string InsetListingsParams::separatedParams(bool keepComma) const { - // , might be used as regular parameter option so - // the prcess might be more complicated than what I am doing here - string opt; - int braces = 0; - 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; + if (keepComma) + return params(",\n"); + else + return params("\n"); } void InsetListingsParams::fromEncodedString(string const & in) { - // Decode string! - // Do nothing because " was silently ignored. - setParams(in); + // Decode string! Reversal of encodedString + string par = in; + // '"' is now &quot; ==> '"' is now &quot; + par = subst(par, """, "\""); + // '"' is now &quot; ==> '"' is now " + par = subst(par, "&", "&"); + setParams(par); } 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 { // is this parameter defined? - if (find(keys_.begin(), keys_.end(), param) == keys_.end()) - return string(); - // if so, search for it - vector pars = getVectorFromString(separatedParams(), "\n"); - for (vector::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(); + map::const_iterator it = params_.find(param); + return (it == params_.end()) ? string() : it->second; } diff --git a/src/insets/InsetListingsParams.h b/src/insets/InsetListingsParams.h index 797cf44d74..221d0aa6cd 100644 --- a/src/insets/InsetListingsParams.h +++ b/src/insets/InsetListingsParams.h @@ -12,7 +12,7 @@ #ifndef INSETLISTINGSPARAMS_H #define INSETLISTINGSPARAMS_H -#include +#include #include #include "Lexer.h" #include "InsetCollapsable.h" @@ -35,7 +35,7 @@ public: void read(Lexer &); /// valid parameter string - std::string params() const { return params_; } + std::string params(std::string sep=",") const; /// add key=value to params_ void addParam(std::string const & key, std::string const & value); @@ -79,12 +79,8 @@ private: /// inline or normal listings bool inline_; - /// listing parameters, this will always be a *valid* string - /// that can be passed to listing packages. - std::string params_; - - /// keys defined in params_ - std::vector keys_; + /// key-value pairs of the parameters + std::map params_; /// collapsable status InsetCollapsable::CollapseStatus status_;