2 * \file InsetCommandParams.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Angus Leeming
10 * Full author contact details are available in file CREDITS.
15 #include "InsetCommandParams.h"
17 #include "InsetBibitem.h"
18 #include "InsetBibtex.h"
19 #include "InsetCitation.h"
20 #include "InsetFloatList.h"
21 #include "InsetHFill.h"
22 #include "InsetHyperlink.h"
23 #include "InsetInclude.h"
24 #include "InsetIndex.h"
25 #include "InsetLabel.h"
26 #include "InsetNomencl.h"
34 #include "support/ExceptionMessage.h"
35 #include "support/lstrings.h"
37 #include <boost/assert.hpp>
42 using support::findToken;
48 using support::ExceptionMessage;
49 using support::WarningException;
51 ICPInfo::ICPInfo(std::string const & s, bool b)
52 : paramName(s), optional(b)
56 void ICPList::addParam(std::string const & s, bool b) {
57 plist_.push_back(ICPInfo(s, b));
61 bool ICPList::hasParam(std::string const & s) {
62 PList::const_iterator it = begin();
63 PList::const_iterator et = end();
64 for (; it != et; ++it) {
65 if (it->paramName == s)
72 InsetCommandParams::InsetCommandParams(InsetCode code)
73 : insetCode_(code), preview_(false)
75 cmdName_ = getDefaultCmd(code);
76 info_ = findInfo(code, cmdName_);
78 params_.resize(info_->n);
82 InsetCommandParams::InsetCommandParams(InsetCode code,
83 string const & cmdName)
84 : insetCode_(code), cmdName_(cmdName), preview_(false)
86 info_ = findInfo(code, cmdName);
88 params_.resize(info_->n);
92 CommandInfo const * InsetCommandParams::findInfo(
93 InsetCode code, std::string const & cmdName)
97 return InsetBibitem::findInfo(cmdName);
99 return InsetBibtex::findInfo(cmdName);
101 return InsetCitation::findInfo(cmdName);
102 case FLOAT_LIST_CODE:
103 return InsetFloatList::findInfo(cmdName);
105 return InsetHFill::findInfo(cmdName);
107 return InsetHyperlink::findInfo(cmdName);
109 return InsetInclude::findInfo(cmdName);
111 return InsetIndex::findInfo(cmdName);
112 case INDEX_PRINT_CODE:
113 return InsetPrintIndex::findInfo(cmdName);
115 return InsetLabel::findInfo(cmdName);
117 return InsetNomencl::findInfo(cmdName);
118 case NOMENCL_PRINT_CODE:
119 return InsetPrintNomencl::findInfo(cmdName);
121 return InsetRef::findInfo(cmdName);
123 return InsetTOC::findInfo(cmdName);
131 std::string InsetCommandParams::getDefaultCmd(InsetCode code) {
134 return InsetBibitem::defaultCommand();
136 return InsetBibtex::defaultCommand();
138 return InsetCitation::defaultCommand();
139 case FLOAT_LIST_CODE:
140 return InsetFloatList::defaultCommand();
142 return InsetHFill::defaultCommand();
144 return InsetHyperlink::defaultCommand();
146 return InsetInclude::defaultCommand();
148 return InsetIndex::defaultCommand();
149 case INDEX_PRINT_CODE:
150 return InsetPrintIndex::defaultCommand();
152 return InsetLabel::defaultCommand();
154 return InsetNomencl::defaultCommand();
155 case NOMENCL_PRINT_CODE:
156 return InsetPrintNomencl::defaultCommand();
158 return InsetRef::defaultCommand();
160 return InsetTOC::defaultCommand();
164 return string(); //silence the warning
168 bool InsetCommandParams::isCompatibleCommand(
169 InsetCode code, std::string const & s)
173 return InsetBibitem::isCompatibleCommand(s);
175 return InsetBibtex::isCompatibleCommand(s);
177 return InsetCitation::isCompatibleCommand(s);
178 case FLOAT_LIST_CODE:
179 return InsetFloatList::isCompatibleCommand(s);
181 return InsetHFill::isCompatibleCommand(s);
183 return InsetHyperlink::isCompatibleCommand(s);
185 return InsetInclude::isCompatibleCommand(s);
187 return InsetIndex::isCompatibleCommand(s);
188 case INDEX_PRINT_CODE:
189 return InsetPrintIndex::isCompatibleCommand(s);
191 return InsetLabel::isCompatibleCommand(s);
193 return InsetNomencl::isCompatibleCommand(s);
194 case NOMENCL_PRINT_CODE:
195 return InsetPrintNomencl::isCompatibleCommand(s);
197 return InsetRef::isCompatibleCommand(s);
199 return InsetTOC::isCompatibleCommand(s);
203 return false; //silence the warning
207 void InsetCommandParams::setCmdName(string const & name)
209 if (!isCompatibleCommand(insetCode_, cmdName_)){
210 lyxerr << "InsetCommand: Incompatible command name " <<
211 name << "." << std::endl;
212 throw ExceptionMessage(WarningException, _("InsetCommand Error: "),
213 from_utf8("Incompatible command name."));
217 CommandInfo const * const info = findInfo(insetCode_, cmdName_);
219 lyxerr << "Command '" << name << "' is not compatible with a '" <<
220 insetType() << "' inset." << std::endl;
223 ParamVector params(info->n);
224 // Overtake parameters with the same name
225 for (size_t i = 0; i < info_->n; ++i) {
226 int j = findToken(info->paramnames, info_->paramnames[i]);
228 params[j] = params_[i];
231 std::swap(params, params_);
235 void InsetCommandParams::read(Lexer & lex)
239 string const insetType = lex.getString();
240 InsetCode const code = insetCode(insetType);
241 if (code != insetCode_) {
242 lex.printError("InsetCommand: Attempt to change type of parameters.");
243 throw ExceptionMessage(WarningException, _("InsetCommand Error: "),
244 from_utf8("Attempt to change type of parameters."));
250 string const test = lex.getString();
251 if (test != "LatexCommand") {
252 lex.printError("InsetCommand: no LatexCommand line found.");
253 throw ExceptionMessage(WarningException, _("InsetCommand error:"),
254 from_utf8("Can't find LatexCommand line."));
258 cmdName_ = lex.getString();
259 if (!isCompatibleCommand(insetCode_, cmdName_)){
260 lex.printError("InsetCommand: Incompatible command name " + cmdName_ + ".");
261 throw ExceptionMessage(WarningException, _("InsetCommand Error: "),
262 from_utf8("Incompatible command name."));
265 info_ = findInfo(insetCode_, cmdName_);
267 lex.printError("InsetCommand: Unknown inset name `$$Token'");
268 throw ExceptionMessage(WarningException,
269 _("Unknown inset name: "), from_utf8(insetType()));
275 token = lex.getString();
276 if (token == "\\end_inset")
278 if (token == "preview") {
280 preview_ = lex.getBool();
283 int const i = findToken(info_->paramnames, token);
286 params_[i] = lex.getDocString();
288 lex.printError("Unknown parameter name `$$Token' for command " + cmdName_);
289 throw ExceptionMessage(WarningException,
290 _("Inset Command: ") + from_ascii(cmdName_),
291 _("Unknown parameter name: ") + from_utf8(token));
294 if (token != "\\end_inset") {
295 lex.printError("Missing \\end_inset at this point. "
297 throw ExceptionMessage(WarningException,
298 _("Missing \\end_inset at this point."),
304 void InsetCommandParams::write(ostream & os) const
306 os << "CommandInset " << insetType() << '\n';
307 os << "LatexCommand " << cmdName_ << '\n';
309 os << "preview true\n";
310 for (size_t i = 0; i < info_->n; ++i)
311 if (!params_[i].empty())
313 os << info_->paramnames[i] << ' '
314 << Lexer::quoteString(to_utf8(params_[i]))
319 docstring const InsetCommandParams::getCommand() const
321 docstring s = '\\' + from_ascii(cmdName_);
323 for (size_t i = 0; i < info_->n; ++i) {
324 if (info_->optional[i]) {
325 if (params_[i].empty()) {
326 // We need to write this parameter even if
327 // it is empty if nonempty optional parameters
328 // follow before the next required parameter.
329 for (size_t j = i + 1; j < info_->n; ++j) {
330 if (!info_->optional[j])
332 if (!params_[j].empty()) {
339 s += '[' + params_[i] + ']';
343 s += '{' + params_[i] + '}';
348 // Make sure that following stuff does not change the
355 docstring const InsetCommandParams::getFirstNonOptParam() const
357 for (size_t i = 0; i < info_->n; ++i)
358 if (!info_->optional[i])
365 docstring const & InsetCommandParams::operator[](string const & name) const
367 int const i = findToken(info_->paramnames, name);
368 BOOST_ASSERT(i >= 0);
373 docstring & InsetCommandParams::operator[](string const & name)
375 int const i = findToken(info_->paramnames, name);
376 BOOST_ASSERT(i >= 0);
381 void InsetCommandParams::clear()
383 for (size_t i = 0; i < info_->n; ++i)
388 bool operator==(InsetCommandParams const & o1,
389 InsetCommandParams const & o2)
391 return o1.insetCode_ == o2.insetCode_ &&
392 o1.cmdName_ == o2.cmdName_ &&
393 o1.info_ == o2.info_ &&
394 o1.params_ == o2.params_ &&
395 o1.preview_ == o2.preview_;
399 bool operator!=(InsetCommandParams const & o1,
400 InsetCommandParams const & o2)