3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
16 #include "BufferView.h"
17 #include "bufferparams.h"
19 #include "FloatList.h"
20 #include "funcrequest.h"
23 #include "paragraph.h"
25 #include "insets/insetbibitem.h"
26 #include "insets/insetbibtex.h"
27 #include "insets/insetcaption.h"
28 #include "insets/insetcite.h"
29 #include "insets/insetcharstyle.h"
30 #include "insets/insetenv.h"
31 #include "insets/insetert.h"
32 #include "insets/insetexternal.h"
33 #include "insets/insetfloat.h"
34 #include "insets/insetfloatlist.h"
35 #include "insets/insetfoot.h"
36 #include "insets/insetgraphics.h"
37 #include "insets/insethfill.h"
38 #include "insets/insetinclude.h"
39 #include "insets/insetindex.h"
40 #include "insets/insetlabel.h"
41 #include "insets/insetline.h"
42 #include "insets/insetmarginal.h"
43 #include "insets/insetnote.h"
44 #include "insets/insetbox.h"
45 #include "insets/insetbranch.h"
46 #include "insets/insetoptarg.h"
47 #include "insets/insetpagebreak.h"
48 #include "insets/insetref.h"
49 #include "insets/insetspace.h"
50 #include "insets/insettabular.h"
51 #include "insets/insettoc.h"
52 #include "insets/inseturl.h"
53 #include "insets/insetvspace.h"
54 #include "insets/insetwrap.h"
56 #include "mathed/math_macrotemplate.h"
57 #include "mathed/math_hullinset.h"
59 #include "support/lstrings.h"
61 #include <boost/assert.hpp>
62 #include <boost/current_function.hpp>
66 using lyx::support::compare_ascii_no_case;
73 InsetBase * createInset(BufferView * bv, FuncRequest const & cmd)
75 BufferParams const & params = bv->buffer()->params();
79 return new InsetHFill;
81 case LFUN_INSERT_LINE:
84 case LFUN_INSERT_PAGEBREAK:
85 return new InsetPagebreak;
87 case LFUN_INSERT_CHARSTYLE: {
88 string s = cmd.getArg(0);
89 LyXTextClass tclass = params.getLyXTextClass();
90 CharStyles::iterator found_cs = tclass.charstyle(s);
91 if (found_cs != tclass.charstyles().end())
92 return new InsetCharStyle(params, found_cs);
94 return new InsetCharStyle(params, s);
97 case LFUN_INSERT_NOTE: {
98 string arg = cmd.getArg(0);
101 return new InsetNote(params, arg);
104 case LFUN_INSERT_BOX: {
105 string arg = cmd.getArg(0);
108 return new InsetBox(params, arg);
111 case LFUN_INSERT_BRANCH: {
112 string arg = cmd.getArg(0);
115 return new InsetBranch(params, InsetBranchParams(arg));
119 return new InsetERT(params);
121 case LFUN_INSET_FOOTNOTE:
122 return new InsetFoot(params);
124 case LFUN_INSET_MARGINAL:
125 return new InsetMarginal(params);
127 case LFUN_INSET_OPTARG:
128 return new InsetOptArg(params);
130 case LFUN_INSERT_BIBITEM:
131 return new InsetBibitem(InsetCommandParams("bibitem"));
133 case LFUN_INSET_FLOAT:
134 // check if the float type exists
135 if (params.getLyXTextClass().floats().typeExist(cmd.argument))
136 return new InsetFloat(params, cmd.argument);
137 lyxerr << "Non-existent float type: " << cmd.argument << endl;
140 case LFUN_INSET_WIDE_FLOAT:
141 // check if the float type exists
142 if (params.getLyXTextClass().floats().typeExist(cmd.argument)) {
143 auto_ptr<InsetFloat> p(new InsetFloat(params, cmd.argument));
144 p->wide(true, params);
147 lyxerr << "Non-existent float type: " << cmd.argument << endl;
150 case LFUN_INSET_WRAP:
151 if (cmd.argument == "figure")
152 return new InsetWrap(params, cmd.argument);
153 lyxerr << "Non-existent floatflt type: " << cmd.argument << endl;
156 case LFUN_INDEX_INSERT: {
157 // Try and generate a valid index entry.
158 InsetCommandParams icp("index");
159 string const contents = cmd.argument.empty() ?
160 bv->getLyXText()->getStringToIndex(bv->cursor()) :
162 icp.setContents(contents);
163 return new InsetIndex(icp);
166 case LFUN_TABULAR_INSERT: {
167 if (cmd.argument.empty())
169 std::istringstream ss(cmd.argument);
176 return new InsetTabular(*bv->buffer(), r, c);
179 case LFUN_INSET_CAPTION: {
180 auto_ptr<InsetCaption> inset(new InsetCaption(params));
181 inset->setAutoBreakRows(true);
182 inset->setDrawFrame(true);
183 inset->setFrameColor(LColor::captionframe);
184 return inset.release();
187 case LFUN_INDEX_PRINT:
188 return new InsetPrintIndex(InsetCommandParams("printindex"));
190 case LFUN_TOC_INSERT:
191 return new InsetTOC(InsetCommandParams("tableofcontents"));
193 case LFUN_ENVIRONMENT_INSERT:
194 return new InsetEnvironment(params, cmd.argument);
197 case LFUN_INSET_LIST:
198 return new InsetList;
200 case LFUN_INSET_THEOREM:
201 return new InsetTheorem;
204 case LFUN_INSET_INSERT: {
205 string const name = cmd.getArg(0);
207 if (name == "bibitem") {
208 InsetCommandParams icp;
209 InsetCommandMailer::string2params(name, cmd.argument,
211 return new InsetBibitem(icp);
213 } else if (name == "bibtex") {
214 InsetCommandParams icp;
215 InsetCommandMailer::string2params(name, cmd.argument,
217 return new InsetBibtex(icp);
219 } else if (name == "citation") {
220 InsetCommandParams icp;
221 InsetCommandMailer::string2params(name, cmd.argument,
223 return new InsetCitation(icp);
225 } else if (name == "ert") {
226 InsetCollapsable::CollapseStatus st;
227 InsetERTMailer::string2params(cmd.argument, st);
228 return new InsetERT(params, st);
230 } else if (name == "external") {
231 Buffer const & buffer = *bv->buffer();
232 InsetExternalParams iep;
233 InsetExternalMailer::string2params(cmd.argument,
235 auto_ptr<InsetExternal> inset(new InsetExternal);
236 inset->setParams(iep, buffer);
237 return inset.release();
239 } else if (name == "graphics") {
240 Buffer const & buffer = *bv->buffer();
241 InsetGraphicsParams igp;
242 InsetGraphicsMailer::string2params(cmd.argument,
244 auto_ptr<InsetGraphics> inset(new InsetGraphics);
245 inset->setParams(igp);
246 return inset.release();
248 } else if (name == "include") {
249 InsetCommandParams iip;
250 InsetIncludeMailer::string2params(cmd.argument, iip);
251 return new InsetInclude(iip);
253 } else if (name == "index") {
254 InsetCommandParams icp;
255 InsetCommandMailer::string2params(name, cmd.argument,
257 return new InsetIndex(icp);
259 } else if (name == "label") {
260 InsetCommandParams icp;
261 InsetCommandMailer::string2params(name, cmd.argument,
263 return new InsetLabel(icp);
265 } else if (name == "ref") {
266 InsetCommandParams icp;
267 InsetCommandMailer::string2params(name, cmd.argument,
269 return new InsetRef(icp, *bv->buffer());
271 } else if (name == "toc") {
272 InsetCommandParams icp;
273 InsetCommandMailer::string2params(name, cmd.argument,
275 return new InsetTOC(icp);
277 } else if (name == "url") {
278 InsetCommandParams icp;
279 InsetCommandMailer::string2params(name, cmd.argument,
281 return new InsetUrl(icp);
283 } else if (name == "vspace") {
285 InsetVSpaceMailer::string2params(cmd.argument, vspace);
286 return new InsetVSpace(vspace);
290 case LFUN_SPACE_INSERT: {
291 string const name = cmd.argument;
292 if (name == "normal")
293 return new InsetSpace(InsetSpace::NORMAL);
294 else if (name == "protected")
295 return new InsetSpace(InsetSpace::PROTECTED);
296 else if (name == "thin")
297 return new InsetSpace(InsetSpace::THIN);
298 else if (name == "quad")
299 return new InsetSpace(InsetSpace::QUAD);
300 else if (name == "qquad")
301 return new InsetSpace(InsetSpace::QQUAD);
302 else if (name == "enspace")
303 return new InsetSpace(InsetSpace::ENSPACE);
304 else if (name == "enskip")
305 return new InsetSpace(InsetSpace::ENSKIP);
306 else if (name == "negthinspace")
307 return new InsetSpace(InsetSpace::NEGTHIN);
308 else if (name.empty())
309 lyxerr << "LyX function 'space' needs an argument." << endl;
311 lyxerr << "Wrong argument for LyX function 'space'." << endl;
324 InsetBase * readInset(LyXLex & lex, Buffer const & buf)
327 if (lex.getString() != "\\begin_inset") {
328 lyxerr << "Buffer::readInset: Consistency check failed."
332 auto_ptr<InsetBase> inset;
334 LyXTextClass tclass = buf.params().getLyXTextClass();
337 string tmptok = lex.getString();
339 // test the different insets
340 if (tmptok == "LatexCommand") {
341 InsetCommandParams inscmd;
344 string const cmdName = inscmd.getCmdName();
346 // This strange command allows LyX to recognize "natbib" style
347 // citations: citet, citep, Citet etc.
348 if (compare_ascii_no_case(cmdName.substr(0,4), "cite") == 0) {
349 inset.reset(new InsetCitation(inscmd));
350 } else if (cmdName == "bibitem") {
351 lex.printError("Wrong place for bibitem");
352 inset.reset(new InsetBibitem(inscmd));
353 } else if (cmdName == "bibtex") {
354 inset.reset(new InsetBibtex(inscmd));
355 } else if (cmdName == "index") {
356 inset.reset(new InsetIndex(inscmd));
357 } else if (cmdName == "include") {
358 inset.reset(new InsetInclude(inscmd));
359 } else if (cmdName == "label") {
360 inset.reset(new InsetLabel(inscmd));
361 } else if (cmdName == "url"
362 || cmdName == "htmlurl") {
363 inset.reset(new InsetUrl(inscmd));
364 } else if (cmdName == "ref"
365 || cmdName == "eqref"
366 || cmdName == "pageref"
368 || cmdName == "vpageref"
369 || cmdName == "prettyref") {
370 if (!inscmd.getOptions().empty()
371 || !inscmd.getContents().empty()) {
372 inset.reset(new InsetRef(inscmd, buf));
374 } else if (cmdName == "tableofcontents") {
375 inset.reset(new InsetTOC(inscmd));
376 } else if (cmdName == "listofalgorithms") {
377 inset.reset(new InsetFloatList("algorithm"));
378 } else if (cmdName == "listoffigures") {
379 inset.reset(new InsetFloatList("figure"));
380 } else if (cmdName == "listoftables") {
381 inset.reset(new InsetFloatList("table"));
382 } else if (cmdName == "printindex") {
383 inset.reset(new InsetPrintIndex(inscmd));
385 lyxerr << "unknown CommandInset '" << cmdName
387 while (lex.isOK() && lex.getString() != "\\end_inset")
392 if (tmptok == "Quotes") {
393 inset.reset(new InsetQuotes);
394 } else if (tmptok == "External") {
395 inset.reset(new InsetExternal);
396 } else if (tmptok == "FormulaMacro") {
397 inset.reset(new MathMacroTemplate);
398 } else if (tmptok == "Formula") {
399 inset.reset(new MathHullInset);
400 } else if (tmptok == "Graphics") {
401 inset.reset(new InsetGraphics);
402 } else if (tmptok == "Note") {
403 inset.reset(new InsetNote(buf.params(), tmptok));
404 } else if (tmptok == "Box") {
405 inset.reset(new InsetBox(buf.params(), tmptok));
406 } else if (tmptok == "CharStyle") {
408 string s = lex.getString();
409 CharStyles::iterator found_cs = tclass.charstyle(s);
410 if (found_cs != tclass.charstyles().end())
411 inset.reset(new InsetCharStyle(buf.params(), found_cs));
414 inset.reset(new InsetCharStyle(buf.params(), s));
416 } else if (tmptok == "Branch") {
417 inset.reset(new InsetBranch(buf.params(),
418 InsetBranchParams()));
419 } else if (tmptok == "Include") {
420 InsetCommandParams p("Include");
421 inset.reset(new InsetInclude(p));
422 } else if (tmptok == "Environment") {
424 inset.reset(new InsetEnvironment(buf.params(), lex.getString()));
425 } else if (tmptok == "ERT") {
426 inset.reset(new InsetERT(buf.params()));
427 } else if (tmptok == "InsetSpace") {
428 inset.reset(new InsetSpace);
429 } else if (tmptok == "Tabular") {
430 inset.reset(new InsetTabular(buf));
431 } else if (tmptok == "Text") {
432 inset.reset(new InsetText(buf.params()));
433 } else if (tmptok == "VSpace") {
434 inset.reset(new InsetVSpace);
435 } else if (tmptok == "Foot") {
436 inset.reset(new InsetFoot(buf.params()));
437 } else if (tmptok == "Marginal") {
438 inset.reset(new InsetMarginal(buf.params()));
439 } else if (tmptok == "OptArg") {
440 inset.reset(new InsetOptArg(buf.params()));
441 } else if (tmptok == "Float") {
443 string tmptok = lex.getString();
444 inset.reset(new InsetFloat(buf.params(), tmptok));
445 } else if (tmptok == "Wrap") {
447 string tmptok = lex.getString();
448 inset.reset(new InsetWrap(buf.params(), tmptok));
450 } else if (tmptok == "List") {
451 inset.reset(new InsetList);
452 } else if (tmptok == "Theorem") {
453 inset.reset(new InsetList);
455 } else if (tmptok == "Caption") {
456 inset.reset(new InsetCaption(buf.params()));
457 } else if (tmptok == "FloatList") {
458 inset.reset(new InsetFloatList);
460 lyxerr << "unknown Inset type '" << tmptok
462 while (lex.isOK() && lex.getString() != "\\end_inset")
467 inset->read(buf, lex);
472 if (inset->lyxCode() == InsetBase::MATHMACRO_CODE) {
473 MathMacroTemplate const * tmpl =
474 static_cast<MathMacroTemplate*>(inset.get());
475 MacroTable::globalMacros().insert
476 (tmpl->name(), tmpl->asMacroData());
478 << BOOST_CURRENT_FUNCTION
479 << ": creating local macro " << tmpl->name()
484 return inset.release();