X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetCommandParams.cpp;h=931e1bb09376111ee656618b3956beffb678d170;hb=e4c46abeb7385960c9dd42494e3c7c1f3e699b56;hp=b803e188240c1fa1fa8aa38d9603e1828720ab66;hpb=826d0fc879be00c2667f937091ee6fc92cba0d60;p=lyx.git diff --git a/src/insets/InsetCommandParams.cpp b/src/insets/InsetCommandParams.cpp index b803e18824..931e1bb093 100644 --- a/src/insets/InsetCommandParams.cpp +++ b/src/insets/InsetCommandParams.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include "InsetCommandParams.h" @@ -23,11 +25,17 @@ #include "InsetInclude.h" #include "InsetIndex.h" #include "InsetLabel.h" +#include "InsetLine.h" #include "InsetNomencl.h" #include "InsetRef.h" #include "InsetTOC.h" +#include "Buffer.h" +#include "Encoding.h" #include "Lexer.h" +#include "OutputParams.h" + +#include "frontends/alert.h" #include "support/debug.h" #include "support/docstream.h" @@ -35,7 +43,7 @@ #include "support/gettext.h" #include "support/lstrings.h" -#include +#include "support/lassert.h" using namespace std; using namespace lyx::support; @@ -43,34 +51,69 @@ using namespace lyx::support; namespace lyx { +/// Get information for \p code and command \p cmdName. +/// Don't call this without first making sure the command name is +/// acceptable to the inset. +static ParamInfo const & findInfo(InsetCode code, string const & cmdName) +{ + switch (code) { + case BIBITEM_CODE: + return InsetBibitem::findInfo(cmdName); + case BIBTEX_CODE: + return InsetBibtex::findInfo(cmdName); + case CITE_CODE: + return InsetCitation::findInfo(cmdName); + case FLOAT_LIST_CODE: + return InsetFloatList::findInfo(cmdName); + case HYPERLINK_CODE: + return InsetHyperlink::findInfo(cmdName); + case INCLUDE_CODE: + return InsetInclude::findInfo(cmdName); + case INDEX_PRINT_CODE: + return InsetPrintIndex::findInfo(cmdName); + case LABEL_CODE: + return InsetLabel::findInfo(cmdName); + case LINE_CODE: + return InsetLine::findInfo(cmdName); + case NOMENCL_CODE: + return InsetNomencl::findInfo(cmdName); + case NOMENCL_PRINT_CODE: + return InsetPrintNomencl::findInfo(cmdName); + case REF_CODE: + return InsetRef::findInfo(cmdName); + case TOC_CODE: + return InsetTOC::findInfo(cmdName); + default: + LATTEST(false); + // fall through in release mode + } + static const ParamInfo pi; + return pi; +} + + ///////////////////////////////////////////////////////////////////// // // ParamInfo::ParamData // ///////////////////////////////////////////////////////////////////// -ParamInfo::ParamData::ParamData(std::string const & s, ParamType t) - : name_(s), type_(t) +ParamInfo::ParamData::ParamData(std::string const & s, ParamType t, + ParamHandling h) + : name_(s), type_(t), handling_(h) {} bool ParamInfo::ParamData::isOptional() const { - return type_ == ParamInfo::LATEX_OPTIONAL - || type_ == ParamInfo::LATEX_KV_OPTIONAL; -} - - -bool ParamInfo::ParamData::isKeyValArg() const -{ - return type_ == ParamInfo::LATEX_KV_REQUIRED - || type_ == ParamInfo::LATEX_KV_OPTIONAL; + return type_ == ParamInfo::LATEX_OPTIONAL; } bool ParamInfo::ParamData::operator==(ParamInfo::ParamData const & rhs) const { - return name() == rhs.name() && type() == rhs.type(); + return name() == rhs.name() && type() == rhs.type() + && handling() == rhs.handling(); } @@ -80,15 +123,16 @@ bool ParamInfo::hasParam(std::string const & name) const const_iterator last = end(); for (; it != last; ++it) { if (it->name() == name) - return !it->isKeyValArg(); + return true; } return false; } -void ParamInfo::add(std::string const & name, ParamType type) +void ParamInfo::add(std::string const & name, ParamType type, + ParamHandling handling) { - info_.push_back(ParamData(name, type)); + info_.push_back(ParamData(name, type, handling)); } @@ -103,14 +147,16 @@ bool ParamInfo::operator==(ParamInfo const & rhs) const ParamInfo::ParamData const & ParamInfo::operator[](std::string const & name) const { - BOOST_ASSERT(hasParam(name)); const_iterator it = begin(); const_iterator last = end(); for (; it != last; ++it) { if (it->name() == name) return *it; } - return *it; // silence warning + LATTEST(false); + // we will try to continue in release mode + static const ParamData pd("asdfghjkl", LYX_INTERNAL); + return pd; } @@ -137,49 +183,14 @@ InsetCommandParams::InsetCommandParams(InsetCode code, } -ParamInfo const & InsetCommandParams::findInfo( - InsetCode code, string const & cmdName) -{ - switch (code) { - case BIBITEM_CODE: - return InsetBibitem::findInfo(cmdName); - case BIBTEX_CODE: - return InsetBibtex::findInfo(cmdName); - case CITE_CODE: - return InsetCitation::findInfo(cmdName); - case FLOAT_LIST_CODE: - return InsetFloatList::findInfo(cmdName); - case HYPERLINK_CODE: - return InsetHyperlink::findInfo(cmdName); - case INCLUDE_CODE: - return InsetInclude::findInfo(cmdName); - case INDEX_PRINT_CODE: - return InsetPrintIndex::findInfo(cmdName); - case LABEL_CODE: - return InsetLabel::findInfo(cmdName); - case NOMENCL_CODE: - return InsetNomencl::findInfo(cmdName); - case NOMENCL_PRINT_CODE: - return InsetPrintNomencl::findInfo(cmdName); - case REF_CODE: - return InsetRef::findInfo(cmdName); - case TOC_CODE: - return InsetTOC::findInfo(cmdName); - default: - BOOST_ASSERT(false); - } - static const ParamInfo pi; - return pi; // to silence the warning -} - - std::string InsetCommandParams::insetType() const { return insetName(insetCode_); } -string InsetCommandParams::getDefaultCmd(InsetCode code) { +string InsetCommandParams::getDefaultCmd(InsetCode code) +{ switch (code) { case BIBITEM_CODE: return InsetBibitem::defaultCommand(); @@ -197,6 +208,8 @@ string InsetCommandParams::getDefaultCmd(InsetCode code) { return InsetPrintIndex::defaultCommand(); case LABEL_CODE: return InsetLabel::defaultCommand(); + case LINE_CODE: + return InsetLine::defaultCommand(); case NOMENCL_CODE: return InsetNomencl::defaultCommand(); case NOMENCL_PRINT_CODE: @@ -206,14 +219,14 @@ string InsetCommandParams::getDefaultCmd(InsetCode code) { case TOC_CODE: return InsetTOC::defaultCommand(); default: - BOOST_ASSERT(false); + LATTEST(false); + // fall through in release mode } - return string(); // silence the warning + return string(); } -bool InsetCommandParams::isCompatibleCommand( - InsetCode code, string const & s) +bool InsetCommandParams::isCompatibleCommand(InsetCode code, string const & s) { switch (code) { case BIBITEM_CODE: @@ -232,6 +245,8 @@ bool InsetCommandParams::isCompatibleCommand( return InsetPrintIndex::isCompatibleCommand(s); case LABEL_CODE: return InsetLabel::isCompatibleCommand(s); + case LINE_CODE: + return InsetLine::isCompatibleCommand(s); case NOMENCL_CODE: return InsetNomencl::isCompatibleCommand(s); case NOMENCL_PRINT_CODE: @@ -240,16 +255,17 @@ bool InsetCommandParams::isCompatibleCommand( return InsetRef::isCompatibleCommand(s); case TOC_CODE: return InsetTOC::isCompatibleCommand(s); - default: - BOOST_ASSERT(false); + default: + LATTEST(false); + // fall through in release mode } - return false; // silence the warning + return false; } void InsetCommandParams::setCmdName(string const & name) { - if (!isCompatibleCommand(insetCode_, cmdName_)){ + if (!isCompatibleCommand(insetCode_, name)) { LYXERR0("InsetCommand: Incompatible command name " << name << "."); throw ExceptionMessage(WarningException, _("InsetCommand Error: "), @@ -263,30 +279,18 @@ void InsetCommandParams::setCmdName(string const & name) void InsetCommandParams::read(Lexer & lex) { - if (lex.isOK()) { - lex.next(); - string const insetType = lex.getString(); - InsetCode const code = insetCode(insetType); - if (code != insetCode_) { - lex.printError("InsetCommandParams: Attempt to change type of inset."); - throw ExceptionMessage(WarningException, _("InsetCommandParams Error: "), - _("Attempt to change type of parameters.")); - } - } + Read(lex, 0); +} - if (lex.isOK()) { - lex.next(); - string const test = lex.getString(); - if (test != "LatexCommand") { - lex.printError("InsetCommandParams: No LatexCommand line found."); - throw ExceptionMessage(WarningException, _("InsetCommandParams error: "), - _("Can't find LatexCommand line.")); - } - } - lex.next(); - cmdName_ = lex.getString(); - if (!isCompatibleCommand(insetCode_, cmdName_)){ - lex.printError("InsetCommandParams: Incompatible command name " + cmdName_ + "."); + +void InsetCommandParams::Read(Lexer & lex, Buffer const * buffer) +{ + lex.setContext("InsetCommandParams::read"); + lex >> insetName(insetCode_).c_str(); + lex >> "LatexCommand"; + lex >> cmdName_; + if (!isCompatibleCommand(insetCode_, cmdName_)) { + lex.printError("Incompatible command name " + cmdName_ + "."); throw ExceptionMessage(WarningException, _("InsetCommandParams Error: "), _("Incompatible command name.")); } @@ -306,7 +310,25 @@ void InsetCommandParams::read(Lexer & lex) } if (info_.hasParam(token)) { lex.next(true); - params_[token] = lex.getDocString(); + docstring data = lex.getDocString(); + if (buffer && token == "filename") { + data = from_utf8(buffer->includedFilePath(to_utf8(data))); + } else if (buffer && token == "bibfiles") { + int i = 0; + docstring newdata; + docstring bib = support::token(data, ',', i); + while (!bib.empty()) { + bib = from_utf8(buffer->includedFilePath(to_utf8(bib), "bib")); + if (!newdata.empty()) + newdata.append(1, ','); + newdata.append(bib); + bib = support::token(data, ',', ++i); + } + data = newdata; + } else if (buffer && token == "options") { + data = from_utf8(buffer->includedFilePath(to_utf8(data), "bst")); + } + params_[token] = data; } else { lex.printError("Unknown parameter name `$$Token' for command " + cmdName_); throw ExceptionMessage(WarningException, @@ -318,13 +340,19 @@ void InsetCommandParams::read(Lexer & lex) lex.printError("Missing \\end_inset at this point. " "Read: `$$Token'"); throw ExceptionMessage(WarningException, - _("Missing \\end_inset at this point."), - from_utf8(token)); + _("InsetCommandParams Error: "), + _("Missing \\end_inset at this point: ") + from_utf8(token)); } } void InsetCommandParams::write(ostream & os) const +{ + Write(os, 0); +} + + +void InsetCommandParams::Write(ostream & os, Buffer const * buffer) const { os << "CommandInset " << insetType() << '\n'; os << "LatexCommand " << cmdName_ << '\n'; @@ -333,55 +361,47 @@ void InsetCommandParams::write(ostream & os) const ParamInfo::const_iterator it = info_.begin(); ParamInfo::const_iterator end = info_.end(); for (; it != end; ++it) { - std::string const & name = it->name(); - docstring const & data = (*this)[name]; + string const & name = it->name(); + string data = to_utf8((*this)[name]); if (!data.empty()) { - // FIXME UNICODE + // Adjust path of files if document was moved + if (buffer && name == "filename") { + data = buffer->includedFilePath(data); + } else if (buffer && name == "bibfiles") { + int i = 0; + string newdata; + string bib = token(data, ',', i); + while (!bib.empty()) { + bib = buffer->includedFilePath(bib, "bib"); + if (!newdata.empty()) + newdata.append(1, ','); + newdata.append(bib); + bib = token(data, ',', ++i); + } + data = newdata; + } else if (buffer && name == "options") { + data = buffer->includedFilePath(data, "bst"); + } os << name << ' ' - << Lexer::quoteString(to_utf8(data)) + << Lexer::quoteString(data) << '\n'; } } } -docstring InsetCommandParams::makeKeyValArgument() const -{ - odocstringstream os; - bool didone = false; - ParamInfo::const_iterator it = info_.begin(); - ParamInfo::const_iterator end = info_.end(); - for (; it != end; ++it) { - if (!it->isKey()) - continue; - string const & name = it->name(); - docstring const & data = (*this)[name]; - if (data.empty()) - continue; - if (didone) - os << ","; - else - didone = true; - os << from_utf8(name) << "=" << data; - } - return os.str(); -} - - bool InsetCommandParams::writeEmptyOptional(ParamInfo::const_iterator ci) const { - if (!ci->isOptional()) - BOOST_ASSERT(false); + LASSERT(ci->isOptional(), return false); + ++ci; // we want to start with the next one ParamInfo::const_iterator end = info_.end(); for (; ci != end; ++ci) { switch (ci->type()) { - case ParamInfo::LATEX_KEY: case ParamInfo::LYX_INTERNAL: break; case ParamInfo::LATEX_REQUIRED: - case ParamInfo::LATEX_KV_REQUIRED: return false; case ParamInfo::LATEX_OPTIONAL: { @@ -392,19 +412,45 @@ bool InsetCommandParams::writeEmptyOptional(ParamInfo::const_iterator ci) const break; } - case ParamInfo::LATEX_KV_OPTIONAL: { - docstring data = makeKeyValArgument(); - if (!data.empty()) - return true; - break; - } } //end switch } return false; } -docstring const InsetCommandParams::getCommand() const +docstring InsetCommandParams::prepareCommand(OutputParams const & runparams, + docstring const & command, + ParamInfo::ParamHandling handling) const +{ + docstring result; + switch (handling) { + case ParamInfo::HANDLING_LATEXIFY: { + pair command_latexed = + runparams.encoding->latexString(command, runparams.dryrun); + result = command_latexed.first; + if (!command_latexed.second.empty()) { + // issue a warning about omitted characters + // FIXME: should be passed to the error dialog + frontend::Alert::warning(_("Uncodable characters"), + bformat(_("The following characters that are used in the inset %1$s are not\n" + "representable in the current encoding and therefore have been omitted:\n%2$s."), + from_utf8(insetType()), command_latexed.second)); + } + break; + } + case ParamInfo::HANDLING_ESCAPE: + result = escape(command); + break; + case ParamInfo::HANDLING_NONE: + result = command; + break; + } // switch + + return result; +} + + +docstring InsetCommandParams::getCommand(OutputParams const & runparams) const { docstring s = '\\' + from_ascii(cmdName_); bool noparam = true; @@ -413,23 +459,19 @@ docstring const InsetCommandParams::getCommand() const for (; it != end; ++it) { std::string const & name = it->name(); switch (it->type()) { - case ParamInfo::LATEX_KEY: case ParamInfo::LYX_INTERNAL: break; case ParamInfo::LATEX_REQUIRED: { - docstring const & data = (*this)[name]; + docstring const data = + prepareCommand(runparams, (*this)[name], it->handling()); s += '{' + data + '}'; noparam = false; break; } - case ParamInfo::LATEX_KV_REQUIRED: { - s += "{" + makeKeyValArgument() + "}"; - noparam = false; - break; - } case ParamInfo::LATEX_OPTIONAL: { - docstring const & data = (*this)[name]; + docstring const data = + prepareCommand(runparams, (*this)[name], it->handling()); if (!data.empty()) { s += '[' + data + ']'; noparam = false; @@ -439,17 +481,6 @@ docstring const InsetCommandParams::getCommand() const } break; } - case ParamInfo::LATEX_KV_OPTIONAL: { - docstring data = makeKeyValArgument(); - if (!data.empty()) { - s += '[' + data + ']'; - noparam = false; - } else if (writeEmptyOptional(it)) { - s += "[]"; - noparam = false; - } - break; - } } //end switch } if (noparam) @@ -460,21 +491,20 @@ docstring const InsetCommandParams::getCommand() const } -docstring const InsetCommandParams::getFirstNonOptParam() const +docstring InsetCommandParams::getFirstNonOptParam() const { ParamInfo::const_iterator it = find_if(info_.begin(), info_.end(), not1(mem_fun_ref(&ParamInfo::ParamData::isOptional))); - if (it == info_.end()) - BOOST_ASSERT(false); + LASSERT(it != info_.end(), return docstring()); return (*this)[it->name()]; } docstring const & InsetCommandParams::operator[](string const & name) const { - static const docstring dummy; //so we don't return a ref to temporary - BOOST_ASSERT(info_.hasParam(name)); + static const docstring dummy; + LASSERT(info_.hasParam(name), return dummy); ParamMap::const_iterator data = params_.find(name); if (data == params_.end() || data->second.empty()) return dummy; @@ -484,7 +514,8 @@ docstring const & InsetCommandParams::operator[](string const & name) const docstring & InsetCommandParams::operator[](string const & name) { - BOOST_ASSERT(info_.hasParam(name)); + LATTEST(info_.hasParam(name)); + // this will add the name in release mode return params_[name]; } @@ -495,19 +526,17 @@ void InsetCommandParams::clear() } -bool operator==(InsetCommandParams const & o1, - InsetCommandParams const & o2) +bool operator==(InsetCommandParams const & o1, InsetCommandParams const & o2) { - return o1.insetCode_ == o2.insetCode_ && - o1.cmdName_ == o2.cmdName_ && - o1.info_ == o2.info_ && - o1.params_ == o2.params_ && - o1.preview_ == o2.preview_; + return o1.insetCode_ == o2.insetCode_ + && o1.cmdName_ == o2.cmdName_ + && o1.info_ == o2.info_ + && o1.params_ == o2.params_ + && o1.preview_ == o2.preview_; } -bool operator!=(InsetCommandParams const & o1, - InsetCommandParams const & o2) +bool operator!=(InsetCommandParams const & o1, InsetCommandParams const & o2) { return !(o1 == o2); }