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 InsetCommandParams::InsetCommandParams(InsetCode code)
52 : insetCode_(code), preview_(false)
54 cmdName_ = getDefaultCmd(code);
55 info_ = findInfo(code, cmdName_);
57 params_.resize(info_->n);
61 InsetCommandParams::InsetCommandParams(InsetCode code,
62 string const & cmdName)
63 : insetCode_(code), cmdName_(cmdName), preview_(false)
65 info_ = findInfo(code, cmdName);
67 params_.resize(info_->n);
71 CommandInfo const * InsetCommandParams::findInfo(
72 InsetCode code, std::string const & cmdName)
76 return InsetBibitem::findInfo(cmdName);
78 return InsetBibtex::findInfo(cmdName);
80 return InsetCitation::findInfo(cmdName);
82 return InsetFloatList::findInfo(cmdName);
84 return InsetHFill::findInfo(cmdName);
86 return InsetHyperlink::findInfo(cmdName);
88 return InsetInclude::findInfo(cmdName);
90 return InsetIndex::findInfo(cmdName);
91 case INDEX_PRINT_CODE:
92 return InsetPrintIndex::findInfo(cmdName);
94 return InsetLabel::findInfo(cmdName);
96 return InsetNomencl::findInfo(cmdName);
97 case NOMENCL_PRINT_CODE:
98 return InsetPrintNomencl::findInfo(cmdName);
100 return InsetRef::findInfo(cmdName);
102 return InsetTOC::findInfo(cmdName);
110 std::string InsetCommandParams::getDefaultCmd(InsetCode code) {
113 return InsetBibitem::defaultCommand();
115 return InsetBibtex::defaultCommand();
117 return InsetCitation::defaultCommand();
118 case FLOAT_LIST_CODE:
119 return InsetFloatList::defaultCommand();
121 return InsetHFill::defaultCommand();
123 return InsetHyperlink::defaultCommand();
125 return InsetInclude::defaultCommand();
127 return InsetIndex::defaultCommand();
128 case INDEX_PRINT_CODE:
129 return InsetPrintIndex::defaultCommand();
131 return InsetLabel::defaultCommand();
133 return InsetNomencl::defaultCommand();
134 case NOMENCL_PRINT_CODE:
135 return InsetPrintNomencl::defaultCommand();
137 return InsetRef::defaultCommand();
139 return InsetTOC::defaultCommand();
143 return string(); //silence the warning
147 bool InsetCommandParams::isCompatibleCommand(
148 InsetCode code, std::string const & s)
152 return InsetBibitem::isCompatibleCommand(s);
154 return InsetBibtex::isCompatibleCommand(s);
156 return InsetCitation::isCompatibleCommand(s);
157 case FLOAT_LIST_CODE:
158 return InsetFloatList::isCompatibleCommand(s);
160 return InsetHFill::isCompatibleCommand(s);
162 return InsetHyperlink::isCompatibleCommand(s);
164 return InsetInclude::isCompatibleCommand(s);
166 return InsetIndex::isCompatibleCommand(s);
167 case INDEX_PRINT_CODE:
168 return InsetPrintIndex::isCompatibleCommand(s);
170 return InsetLabel::isCompatibleCommand(s);
172 return InsetNomencl::isCompatibleCommand(s);
173 case NOMENCL_PRINT_CODE:
174 return InsetPrintNomencl::isCompatibleCommand(s);
176 return InsetRef::isCompatibleCommand(s);
178 return InsetTOC::isCompatibleCommand(s);
182 return false; //silence the warning
186 void InsetCommandParams::setCmdName(string const & name)
188 if (!isCompatibleCommand(insetCode_, cmdName_)){
189 lyxerr << "InsetCommand: Incompatible command name " <<
190 name << "." << std::endl;
191 throw ExceptionMessage(WarningException, _("InsetCommand Error: "),
192 from_utf8("Incompatible command name."));
196 CommandInfo const * const info = findInfo(insetCode_, cmdName_);
198 lyxerr << "Command '" << name << "' is not compatible with a '" <<
199 insetType() << "' inset." << std::endl;
202 ParamVector params(info->n);
203 // Overtake parameters with the same name
204 for (size_t i = 0; i < info_->n; ++i) {
205 int j = findToken(info->paramnames, info_->paramnames[i]);
207 params[j] = params_[i];
210 std::swap(params, params_);
214 void InsetCommandParams::read(Lexer & lex)
218 string const insetType = lex.getString();
219 InsetCode const code = insetCode(insetType);
220 if (code != insetCode_) {
221 lex.printError("InsetCommand: Attempt to change type of parameters.");
222 throw ExceptionMessage(WarningException, _("InsetCommand Error: "),
223 from_utf8("Attempt to change type of parameters."));
229 string const test = lex.getString();
230 if (test != "LatexCommand") {
231 lex.printError("InsetCommand: no LatexCommand line found.");
232 throw ExceptionMessage(WarningException, _("InsetCommand error:"),
233 from_utf8("Can't find LatexCommand line."));
237 cmdName_ = lex.getString();
238 if (!isCompatibleCommand(insetCode_, cmdName_)){
239 lex.printError("InsetCommand: Incompatible command name " + cmdName_ + ".");
240 throw ExceptionMessage(WarningException, _("InsetCommand Error: "),
241 from_utf8("Incompatible command name."));
244 info_ = findInfo(insetCode_, cmdName_);
246 lex.printError("InsetCommand: Unknown inset name `$$Token'");
247 throw ExceptionMessage(WarningException,
248 _("Unknown inset name: "), from_utf8(insetType()));
254 token = lex.getString();
255 if (token == "\\end_inset")
257 if (token == "preview") {
259 preview_ = lex.getBool();
262 int const i = findToken(info_->paramnames, token);
265 params_[i] = lex.getDocString();
267 lex.printError("Unknown parameter name `$$Token' for command " + cmdName_);
268 throw ExceptionMessage(WarningException,
269 _("Inset Command: ") + from_ascii(cmdName_),
270 _("Unknown parameter name: ") + from_utf8(token));
273 if (token != "\\end_inset") {
274 lex.printError("Missing \\end_inset at this point. "
276 throw ExceptionMessage(WarningException,
277 _("Missing \\end_inset at this point."),
283 void InsetCommandParams::write(ostream & os) const
285 os << "CommandInset " << insetType() << '\n';
286 os << "LatexCommand " << cmdName_ << '\n';
288 os << "preview true\n";
289 for (size_t i = 0; i < info_->n; ++i)
290 if (!params_[i].empty())
292 os << info_->paramnames[i] << ' '
293 << Lexer::quoteString(to_utf8(params_[i]))
298 docstring const InsetCommandParams::getCommand() const
300 docstring s = '\\' + from_ascii(cmdName_);
302 for (size_t i = 0; i < info_->n; ++i) {
303 if (info_->optional[i]) {
304 if (params_[i].empty()) {
305 // We need to write this parameter even if
306 // it is empty if nonempty optional parameters
307 // follow before the next required parameter.
308 for (size_t j = i + 1; j < info_->n; ++j) {
309 if (!info_->optional[j])
311 if (!params_[j].empty()) {
318 s += '[' + params_[i] + ']';
322 s += '{' + params_[i] + '}';
327 // Make sure that following stuff does not change the
334 docstring const InsetCommandParams::getFirstNonOptParam() const
336 for (size_t i = 0; i < info_->n; ++i)
337 if (!info_->optional[i])
344 docstring const & InsetCommandParams::operator[](string const & name) const
346 int const i = findToken(info_->paramnames, name);
347 BOOST_ASSERT(i >= 0);
352 docstring & InsetCommandParams::operator[](string const & name)
354 int const i = findToken(info_->paramnames, name);
355 BOOST_ASSERT(i >= 0);
360 void InsetCommandParams::clear()
362 for (size_t i = 0; i < info_->n; ++i)
367 bool operator==(InsetCommandParams const & o1,
368 InsetCommandParams const & o2)
370 return o1.insetCode_ == o2.insetCode_ &&
371 o1.cmdName_ == o2.cmdName_ &&
372 o1.info_ == o2.info_ &&
373 o1.params_ == o2.params_ &&
374 o1.preview_ == o2.preview_;
378 bool operator!=(InsetCommandParams const & o1,
379 InsetCommandParams const & o2)