2 * \file InsetInclude.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Lars Gullik Bjønnes
8 * Full author contact details are available in file CREDITS.
13 #include "InsetInclude.h"
16 #include "buffer_funcs.h"
17 #include "BufferList.h"
18 #include "BufferParams.h"
19 #include "BufferView.h"
22 #include "DispatchResult.h"
24 #include "FuncRequest.h"
25 #include "FuncStatus.h"
27 #include "LaTeXFeatures.h"
31 #include "MetricsInfo.h"
32 #include "OutputParams.h"
33 #include "TocBackend.h"
35 #include "frontends/alert.h"
36 #include "frontends/Painter.h"
38 #include "graphics/PreviewImage.h"
39 #include "graphics/PreviewLoader.h"
41 #include "insets/RenderPreview.h"
42 #include "insets/InsetListingsParams.h"
44 #include "support/filetools.h"
45 #include "support/lstrings.h" // contains
46 #include "support/lyxalgo.h"
47 #include "support/lyxlib.h"
48 #include "support/convert.h"
50 #include <boost/bind.hpp>
55 // Implementation is in LyX.cpp
56 extern void dispatch(FuncRequest const & action);
58 using support::addName;
59 using support::absolutePath;
60 using support::bformat;
61 using support::changeExtension;
62 using support::contains;
64 using support::DocFileName;
65 using support::FileName;
66 using support::getFileContents;
67 using support::getVectorFromString;
68 using support::isLyXFilename;
69 using support::isValidLaTeXFilename;
70 using support::latex_path;
71 using support::makeAbsPath;
72 using support::makeDisplayPath;
73 using support::makeRelPath;
74 using support::onlyFilename;
75 using support::onlyPath;
76 using support::prefixIs;
83 using std::istringstream;
85 using std::ostringstream;
88 namespace Alert = frontend::Alert;
93 docstring const uniqueID()
95 static unsigned int seed = 1000;
96 return "file" + convert<docstring>(++seed);
100 bool isListings(InsetCommandParams const & params)
102 return params.getCmdName() == "lstinputlisting";
108 InsetInclude::InsetInclude(InsetCommandParams const & p)
109 : params_(p), include_label(uniqueID()),
110 preview_(new RenderMonitoredPreview(this)),
113 preview_->fileChanged(boost::bind(&InsetInclude::fileChanged, this));
117 InsetInclude::InsetInclude(InsetInclude const & other)
119 params_(other.params_),
120 include_label(other.include_label),
121 preview_(new RenderMonitoredPreview(this)),
124 preview_->fileChanged(boost::bind(&InsetInclude::fileChanged, this));
128 InsetInclude::~InsetInclude()
130 InsetIncludeMailer(*this).hideDialog();
134 void InsetInclude::doDispatch(Cursor & cur, FuncRequest & cmd)
136 switch (cmd.action) {
138 case LFUN_INSET_MODIFY: {
139 InsetCommandParams p(INCLUDE_CODE);
140 InsetIncludeMailer::string2params(to_utf8(cmd.argument()), p);
141 if (!p.getCmdName().empty()) {
143 InsetListingsParams par_old(params().getOptions());
144 InsetListingsParams par_new(p.getOptions());
145 if (par_old.getParamValue("label") !=
146 par_new.getParamValue("label")
147 && !par_new.getParamValue("label").empty())
148 cur.bv().buffer().changeRefsIfUnique(
149 from_utf8(par_old.getParamValue("label")),
150 from_utf8(par_new.getParamValue("label")),
153 set(p, cur.buffer());
154 cur.buffer().updateBibfilesCache();
160 case LFUN_INSET_DIALOG_UPDATE:
161 InsetIncludeMailer(*this).updateDialog(&cur.bv());
164 case LFUN_MOUSE_RELEASE:
165 if (!cur.selection())
166 InsetIncludeMailer(*this).showDialog(&cur.bv());
170 Inset::doDispatch(cur, cmd);
176 bool InsetInclude::getStatus(Cursor & cur, FuncRequest const & cmd,
177 FuncStatus & flag) const
179 switch (cmd.action) {
181 case LFUN_INSET_MODIFY:
182 case LFUN_INSET_DIALOG_UPDATE:
187 return Inset::getStatus(cur, cmd, flag);
192 InsetCommandParams const & InsetInclude::params() const
200 /// the type of inclusion
210 Types type(InsetCommandParams const & params)
212 string const command_name = params.getCmdName();
214 if (command_name == "input")
216 if (command_name == "verbatiminput")
218 if (command_name == "verbatiminput*")
220 if (command_name == "lstinputlisting")
226 bool isVerbatim(InsetCommandParams const & params)
228 string const command_name = params.getCmdName();
229 return command_name == "verbatiminput" ||
230 command_name == "verbatiminput*";
234 bool isInputOrInclude(InsetCommandParams const & params)
236 Types const t = type(params);
237 return (t == INPUT) || (t == INCLUDE);
241 string const masterFilename(Buffer const & buffer)
243 return buffer.getMasterBuffer()->fileName();
247 string const parentFilename(Buffer const & buffer)
249 return buffer.fileName();
253 FileName const includedFilename(Buffer const & buffer,
254 InsetCommandParams const & params)
256 return makeAbsPath(to_utf8(params["filename"]),
257 onlyPath(parentFilename(buffer)));
261 void add_preview(RenderMonitoredPreview &, InsetInclude const &, Buffer const &);
266 void InsetInclude::set(InsetCommandParams const & p, Buffer const & buffer)
271 if (preview_->monitoring())
272 preview_->stopMonitoring();
274 if (type(params_) == INPUT)
275 add_preview(*preview_, *this, buffer);
279 Inset * InsetInclude::clone() const
281 return new InsetInclude(*this);
285 void InsetInclude::write(Buffer const &, ostream & os) const
291 void InsetInclude::write(ostream & os) const
293 os << "Include " << to_utf8(params_.getCommand()) << '\n'
294 << "preview " << convert<string>(params_.preview()) << '\n';
298 void InsetInclude::read(Buffer const &, Lexer & lex)
304 void InsetInclude::read(Lexer & lex)
308 string const command = lex.getString();
309 params_.scanCommand(command);
314 token = lex.getString();
315 if (token == "\\end_inset")
317 if (token == "preview") {
319 params_.preview(lex.getBool());
321 lex.printError("Unknown parameter name `$$Token' for command " + params_.getCmdName());
323 if (token != "\\end_inset") {
324 lex.printError("Missing \\end_inset at this point. "
330 docstring const InsetInclude::getScreenLabel(Buffer const & buf) const
334 switch (type(params_)) {
336 temp = buf.B_("Input");
339 temp = buf.B_("Verbatim Input");
342 temp = buf.B_("Verbatim Input*");
345 temp = buf.B_("Include");
348 temp = listings_label_;
354 if (params_["filename"].empty())
357 temp += from_utf8(onlyFilename(to_utf8(params_["filename"])));
365 /// return the child buffer if the file is a LyX doc and is loaded
366 Buffer * getChildBuffer(Buffer const & buffer, InsetCommandParams const & params)
368 if (isVerbatim(params) || isListings(params))
371 string const included_file = includedFilename(buffer, params).absFilename();
372 if (!isLyXFilename(included_file))
375 Buffer * childBuffer = theBufferList().getBuffer(included_file);
377 //FIXME RECURSIVE INCLUDES
378 if (childBuffer == & buffer)
387 /// return true if the file is or got loaded.
388 Buffer * loadIfNeeded(Buffer const & parent, InsetCommandParams const & params)
390 if (isVerbatim(params) || isListings(params))
393 string const parent_filename = parent.fileName();
394 FileName const included_file = makeAbsPath(to_utf8(params["filename"]),
395 onlyPath(parent_filename));
397 if (!isLyXFilename(included_file.absFilename()))
400 Buffer * child = theBufferList().getBuffer(included_file.absFilename());
402 // the readonly flag can/will be wrong, not anymore I think.
403 if (!included_file.exists())
406 child = theBufferList().newBuffer(included_file.absFilename());
407 if (!loadLyXFile(child, included_file)) {
408 //close the buffer we just opened
409 theBufferList().close(child, false);
413 child->setParentName(parent_filename);
418 int InsetInclude::latex(Buffer const & buffer, odocstream & os,
419 OutputParams const & runparams) const
421 string incfile(to_utf8(params_["filename"]));
423 // Do nothing if no file name has been specified
427 FileName const included_file(includedFilename(buffer, params_));
429 //Check we're not trying to include ourselves.
430 //FIXME RECURSIVE INCLUDE
431 //This isn't sufficient, as the inclusion could be downstream.
432 //But it'll have to do for now.
433 if (isInputOrInclude(params_) &&
434 buffer.fileName() == included_file.absFilename())
436 Alert::error(_("Recursive input"),
437 bformat(_("Attempted to include file %1$s in itself! "
438 "Ignoring inclusion."), from_utf8(incfile)));
442 Buffer const * const m_buffer = buffer.getMasterBuffer();
444 // if incfile is relative, make it relative to the master
446 if (!absolutePath(incfile)) {
448 incfile = to_utf8(makeRelPath(from_utf8(included_file.absFilename()),
449 from_utf8(m_buffer->filePath())));
452 // write it to a file (so far the complete file)
453 string const exportfile = changeExtension(incfile, ".tex");
454 string const mangled =
455 DocFileName(changeExtension(included_file.absFilename(),".tex")).
457 FileName const writefile(makeAbsPath(mangled, m_buffer->temppath()));
461 else if (!isValidLaTeXFilename(incfile)) {
462 frontend::Alert::warning(_("Invalid filename"),
463 _("The following filename is likely to cause trouble "
464 "when running the exported file through LaTeX: ") +
467 LYXERR(Debug::LATEX) << "incfile:" << incfile << endl;
468 LYXERR(Debug::LATEX) << "exportfile:" << exportfile << endl;
469 LYXERR(Debug::LATEX) << "writefile:" << writefile << endl;
471 if (runparams.inComment || runparams.dryrun) {
472 //Don't try to load or copy the file if we're
473 //in a comment or doing a dryrun
474 } else if (isInputOrInclude(params_) &&
475 isLyXFilename(included_file.absFilename())) {
476 //if it's a LyX file and we're inputting or including,
477 //try to load it so we can write the associated latex
478 if (!loadIfNeeded(buffer, params_))
481 Buffer * tmp = theBufferList().getBuffer(included_file.absFilename());
483 if (tmp->params().getBaseClass() != m_buffer->params().getBaseClass()) {
485 docstring text = bformat(_("Included file `%1$s'\n"
486 "has textclass `%2$s'\n"
487 "while parent file has textclass `%3$s'."),
488 makeDisplayPath(included_file.absFilename()),
489 from_utf8(tmp->params().getTextClass().name()),
490 from_utf8(m_buffer->params().getTextClass().name()));
491 Alert::warning(_("Different textclasses"), text);
495 // Make sure modules used in child are all included in master
496 //FIXME It might be worth loading the children's modules into the master
497 //over in BufferParams rather than doing this check.
498 vector<string> const masterModules = m_buffer->params().getModules();
499 vector<string> const childModules = tmp->params().getModules();
500 vector<string>::const_iterator it = childModules.begin();
501 vector<string>::const_iterator end = childModules.end();
502 for (; it != end; ++it) {
503 string const module = *it;
504 vector<string>::const_iterator found =
505 find(masterModules.begin(), masterModules.end(), module);
506 if (found != masterModules.end()) {
507 docstring text = bformat(_("Included file `%1$s'\n"
508 "uses module `%2$s'\n"
509 "which is not used in parent file."),
510 makeDisplayPath(included_file.absFilename()), from_utf8(module));
511 Alert::warning(_("Module not found"), text);
515 tmp->markDepClean(m_buffer->temppath());
517 // FIXME: handle non existing files
518 // FIXME: Second argument is irrelevant!
519 // since only_body is true, makeLaTeXFile will not look at second
520 // argument. Should we set it to string(), or should makeLaTeXFile
521 // make use of it somehow? (JMarc 20031002)
522 // The included file might be written in a different encoding
523 Encoding const * const oldEnc = runparams.encoding;
524 runparams.encoding = &tmp->params().encoding();
525 tmp->makeLaTeXFile(writefile,
526 onlyPath(masterFilename(buffer)),
528 runparams.encoding = oldEnc;
530 // In this case, it's not a LyX file, so we copy the file
531 // to the temp dir, so that .aux files etc. are not created
532 // in the original dir. Files included by this file will be
533 // found via input@path, see ../Buffer.cpp.
534 unsigned long const checksum_in = sum(included_file);
535 unsigned long const checksum_out = sum(writefile);
537 if (checksum_in != checksum_out) {
538 if (!copy(included_file, writefile)) {
541 << to_utf8(bformat(_("Could not copy the file\n%1$s\n"
542 "into the temporary directory."),
543 from_utf8(included_file.absFilename())))
550 string const tex_format = (runparams.flavor == OutputParams::LATEX) ?
551 "latex" : "pdflatex";
552 if (isVerbatim(params_)) {
553 incfile = latex_path(incfile);
555 os << '\\' << from_ascii(params_.getCmdName()) << '{'
556 << from_utf8(incfile) << '}';
557 } else if (type(params_) == INPUT) {
558 runparams.exportdata->addExternalFile(tex_format, writefile,
561 // \input wants file with extension (default is .tex)
562 if (!isLyXFilename(included_file.absFilename())) {
563 incfile = latex_path(incfile);
565 os << '\\' << from_ascii(params_.getCmdName())
566 << '{' << from_utf8(incfile) << '}';
568 incfile = changeExtension(incfile, ".tex");
569 incfile = latex_path(incfile);
571 os << '\\' << from_ascii(params_.getCmdName())
572 << '{' << from_utf8(incfile) << '}';
574 } else if (type(params_) == LISTINGS) {
575 os << '\\' << from_ascii(params_.getCmdName());
576 string opt = params_.getOptions();
577 // opt is set in QInclude dialog and should have passed validation.
578 InsetListingsParams params(opt);
579 if (!params.params().empty())
580 os << "[" << from_utf8(params.params()) << "]";
581 os << '{' << from_utf8(incfile) << '}';
583 runparams.exportdata->addExternalFile(tex_format, writefile,
586 // \include don't want extension and demands that the
587 // file really have .tex
588 incfile = changeExtension(incfile, string());
589 incfile = latex_path(incfile);
591 os << '\\' << from_ascii(params_.getCmdName()) << '{'
592 << from_utf8(incfile) << '}';
599 int InsetInclude::plaintext(Buffer const & buffer, odocstream & os,
600 OutputParams const &) const
602 if (isVerbatim(params_) || isListings(params_)) {
603 os << '[' << getScreenLabel(buffer) << '\n';
604 // FIXME: We don't know the encoding of the file
605 docstring const str =
606 from_utf8(getFileContents(includedFilename(buffer, params_)));
609 return PLAINTEXT_NEWLINE + 1; // one char on a separate line
611 docstring const str = '[' + getScreenLabel(buffer) + ']';
618 int InsetInclude::docbook(Buffer const & buffer, odocstream & os,
619 OutputParams const & runparams) const
621 string incfile = to_utf8(params_["filename"]);
623 // Do nothing if no file name has been specified
627 string const included_file = includedFilename(buffer, params_).absFilename();
629 //Check we're not trying to include ourselves.
630 //FIXME RECURSIVE INCLUDE
631 //This isn't sufficient, as the inclusion could be downstream.
632 //But it'll have to do for now.
633 if (buffer.fileName() == included_file) {
634 Alert::error(_("Recursive input"),
635 bformat(_("Attempted to include file %1$s in itself! "
636 "Ignoring inclusion."), from_utf8(incfile)));
640 // write it to a file (so far the complete file)
641 string const exportfile = changeExtension(incfile, ".sgml");
642 DocFileName writefile(changeExtension(included_file, ".sgml"));
644 if (loadIfNeeded(buffer, params_)) {
645 Buffer * tmp = theBufferList().getBuffer(included_file);
647 string const mangled = writefile.mangledFilename();
648 writefile = makeAbsPath(mangled,
649 buffer.getMasterBuffer()->temppath());
653 LYXERR(Debug::LATEX) << "incfile:" << incfile << endl;
654 LYXERR(Debug::LATEX) << "exportfile:" << exportfile << endl;
655 LYXERR(Debug::LATEX) << "writefile:" << writefile << endl;
657 tmp->makeDocBookFile(writefile, runparams, true);
660 runparams.exportdata->addExternalFile("docbook", writefile,
662 runparams.exportdata->addExternalFile("docbook-xml", writefile,
665 if (isVerbatim(params_) || isListings(params_)) {
666 os << "<inlinegraphic fileref=\""
667 << '&' << include_label << ';'
668 << "\" format=\"linespecific\">";
670 os << '&' << include_label << ';';
676 void InsetInclude::validate(LaTeXFeatures & features) const
678 string incfile(to_utf8(params_["filename"]));
681 Buffer const & buffer = features.buffer();
683 string const included_file = includedFilename(buffer, params_).absFilename();
685 if (isLyXFilename(included_file))
686 writefile = changeExtension(included_file, ".sgml");
688 writefile = included_file;
690 if (!features.runparams().nice && !isVerbatim(params_) && !isListings(params_)) {
691 incfile = DocFileName(writefile).mangledFilename();
692 writefile = makeAbsPath(incfile,
693 buffer.getMasterBuffer()->temppath()).absFilename();
696 features.includeFile(include_label, writefile);
698 if (isVerbatim(params_))
699 features.require("verbatim");
700 else if (isListings(params_))
701 features.require("listings");
703 // Here we must do the fun stuff...
704 // Load the file in the include if it needs
706 if (loadIfNeeded(buffer, params_)) {
708 Buffer * const tmp = theBufferList().getBuffer(included_file);
709 // make sure the buffer isn't us
710 // FIXME RECURSIVE INCLUDES
711 // This is not sufficient, as recursive includes could be
712 // more than a file away. But it will do for now.
713 if (tmp && tmp != & buffer) {
714 // We must temporarily change features.buffer,
715 // otherwise it would always be the master buffer,
716 // and nested includes would not work.
717 features.setBuffer(*tmp);
718 tmp->validate(features);
719 features.setBuffer(buffer);
725 void InsetInclude::getLabelList(Buffer const & buffer,
726 std::vector<docstring> & list) const
728 if (isListings(params_)) {
729 InsetListingsParams params(params_.getOptions());
730 string label = params.getParamValue("label");
732 list.push_back(from_utf8(label));
734 else if (loadIfNeeded(buffer, params_)) {
735 string const included_file = includedFilename(buffer, params_).absFilename();
736 Buffer * tmp = theBufferList().getBuffer(included_file);
737 tmp->setParentName("");
738 tmp->getLabelList(list);
739 tmp->setParentName(parentFilename(buffer));
744 void InsetInclude::fillWithBibKeys(Buffer const & buffer,
745 BiblioInfo & keys, InsetIterator const & /*di*/) const
747 if (loadIfNeeded(buffer, params_)) {
748 string const included_file = includedFilename(buffer, params_).absFilename();
749 Buffer * tmp = theBufferList().getBuffer(included_file);
750 //FIXME This is kind of a dirty hack and should be made reasonable.
751 tmp->setParentName("");
752 keys.fillWithBibKeys(tmp);
753 tmp->setParentName(parentFilename(buffer));
758 void InsetInclude::updateBibfilesCache(Buffer const & buffer)
760 Buffer * const tmp = getChildBuffer(buffer, params_);
762 tmp->setParentName("");
763 tmp->updateBibfilesCache();
764 tmp->setParentName(parentFilename(buffer));
769 std::vector<FileName> const &
770 InsetInclude::getBibfilesCache(Buffer const & buffer) const
772 Buffer * const tmp = getChildBuffer(buffer, params_);
774 tmp->setParentName("");
775 std::vector<FileName> const & cache = tmp->getBibfilesCache();
776 tmp->setParentName(parentFilename(buffer));
779 static std::vector<FileName> const empty;
784 void InsetInclude::metrics(MetricsInfo & mi, Dimension & dim) const
786 BOOST_ASSERT(mi.base.bv);
788 bool use_preview = false;
789 if (RenderPreview::status() != LyXRC::PREVIEW_OFF) {
790 graphics::PreviewImage const * pimage =
791 preview_->getPreviewImage(mi.base.bv->buffer());
792 use_preview = pimage && pimage->image();
796 preview_->metrics(mi, dim);
800 button_.update(getScreenLabel(mi.base.bv->buffer()),
803 button_.metrics(mi, dim);
806 Box b(0, dim.wid, -dim.asc, dim.des);
811 void InsetInclude::draw(PainterInfo & pi, int x, int y) const
813 BOOST_ASSERT(pi.base.bv);
815 bool use_preview = false;
816 if (RenderPreview::status() != LyXRC::PREVIEW_OFF) {
817 graphics::PreviewImage const * pimage =
818 preview_->getPreviewImage(pi.base.bv->buffer());
819 use_preview = pimage && pimage->image();
823 preview_->draw(pi, x, y);
825 button_.draw(pi, x, y);
829 Inset::DisplayType InsetInclude::display() const
831 return type(params_) == INPUT ? Inline : AlignCenter;
840 void InsetInclude::fileChanged() const
842 Buffer const * const buffer_ptr = LyX::cref().updateInset(this);
846 Buffer const & buffer = *buffer_ptr;
847 preview_->removePreview(buffer);
848 add_preview(*preview_.get(), *this, buffer);
849 preview_->startLoading(buffer);
855 bool preview_wanted(InsetCommandParams const & params, Buffer const & buffer)
857 FileName const included_file = includedFilename(buffer, params);
859 return type(params) == INPUT && params.preview() &&
860 included_file.isFileReadable();
864 docstring const latex_string(InsetInclude const & inset, Buffer const & buffer)
867 // We don't need to set runparams.encoding since this will be done
868 // by latex() anyway.
869 OutputParams runparams(0);
870 runparams.flavor = OutputParams::LATEX;
871 inset.latex(buffer, os, runparams);
877 void add_preview(RenderMonitoredPreview & renderer, InsetInclude const & inset,
878 Buffer const & buffer)
880 InsetCommandParams const & params = inset.params();
881 if (RenderPreview::status() != LyXRC::PREVIEW_OFF &&
882 preview_wanted(params, buffer)) {
883 renderer.setAbsFile(includedFilename(buffer, params));
884 docstring const snippet = latex_string(inset, buffer);
885 renderer.addPreview(snippet, buffer);
892 void InsetInclude::addPreview(graphics::PreviewLoader & ploader) const
894 Buffer const & buffer = ploader.buffer();
895 if (preview_wanted(params(), buffer)) {
896 preview_->setAbsFile(includedFilename(buffer, params()));
897 docstring const snippet = latex_string(*this, buffer);
898 preview_->addPreview(snippet, ploader);
903 void InsetInclude::addToToc(TocList & toclist, Buffer const & buffer, ParConstIterator const & pit) const
905 if (isListings(params_)) {
906 InsetListingsParams params(params_.getOptions());
907 string caption = params.getParamValue("caption");
908 if (!caption.empty()) {
909 Toc & toc = toclist["listing"];
910 docstring const str = convert<docstring>(toc.size() + 1)
911 + ". " + from_utf8(caption);
912 // This inset does not have a valid ParConstIterator
913 // so it has to use the iterator of its parent paragraph
914 toc.push_back(TocItem(pit, 0, str));
918 Buffer const * const childbuffer = getChildBuffer(buffer, params_);
922 TocList const & childtoclist = childbuffer->tocBackend().tocs();
923 TocList::const_iterator it = childtoclist.begin();
924 TocList::const_iterator const end = childtoclist.end();
925 for(; it != end; ++it)
926 toclist[it->first].insert(toclist[it->first].end(),
927 it->second.begin(), it->second.end());
931 void InsetInclude::updateLabels(Buffer const & buffer,
934 Buffer const * const childbuffer = getChildBuffer(buffer, params_);
936 lyx::updateLabels(*childbuffer, true);
937 else if (isListings(params_)) {
938 InsetListingsParams const par = params_.getOptions();
939 if (par.getParamValue("caption").empty())
940 listings_label_.clear();
942 Counters & counters = buffer.params().getTextClass().counters();
943 docstring const cnt = from_ascii("listing");
944 if (counters.hasCounter(cnt)) {
946 listings_label_ = buffer.B_("Program Listing ") + convert<docstring>(counters.value(cnt));
948 listings_label_ = buffer.B_("Program Listing");
954 void InsetInclude::registerEmbeddedFiles(Buffer const & buffer,
955 EmbeddedFiles & files) const
957 // include and input are temprarily not considered.
958 if (isVerbatim(params_) || isListings(params_))
959 files.registerFile(includedFilename(buffer, params_).absFilename(),
964 string const InsetIncludeMailer::name_("include");
966 InsetIncludeMailer::InsetIncludeMailer(InsetInclude & inset)
971 string const InsetIncludeMailer::inset2string(Buffer const &) const
973 return params2string(inset_.params());
977 void InsetIncludeMailer::string2params(string const & in,
978 InsetCommandParams & params)
984 istringstream data(in);
990 if (!lex || name != name_)
991 return print_mailer_error("InsetIncludeMailer", in, 1, name_);
993 // This is part of the inset proper that is usually swallowed
994 // by Text::readInset
997 if (!lex || id != "Include")
998 return print_mailer_error("InsetIncludeMailer", in, 2, "Include");
1000 InsetInclude inset(params);
1002 params = inset.params();
1007 InsetIncludeMailer::params2string(InsetCommandParams const & params)
1009 InsetInclude inset(params);
1011 data << name_ << ' ';
1013 data << "\\end_inset\n";