X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetInclude.cpp;h=870310ef2ddaa9c03f3186ee18d4fc39f29f3939;hb=eb294eadb5e7f22880da399ae082f74567bbfc4e;hp=6eba05abde51d319d7ab81cc6cd49e3c4df05c76;hpb=5d4e6dfb68cfa045e4929fc0b49a89a8f6686ab0;p=lyx.git diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index 6eba05abde..870310ef2d 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -4,7 +4,7 @@ * Licence details can be found in the file COPYING. * * \author Lars Gullik Bjønnes - * \author Richard Heck (conversion to InsetCommand) + * \author Richard Kimberly Heck (conversion to InsetCommand) * * Full author contact details are available in file CREDITS. */ @@ -20,7 +20,6 @@ #include "BufferView.h" #include "Converter.h" #include "Cursor.h" -#include "DispatchResult.h" #include "Encoding.h" #include "ErrorList.h" #include "Exporter.h" @@ -28,14 +27,11 @@ #include "FuncRequest.h" #include "FuncStatus.h" #include "LaTeXFeatures.h" -#include "LayoutFile.h" #include "LayoutModuleList.h" #include "LyX.h" -#include "Lexer.h" #include "MetricsInfo.h" #include "output_plaintext.h" #include "output_xhtml.h" -#include "OutputParams.h" #include "texstream.h" #include "TextClass.h" #include "TocBackend.h" @@ -61,7 +57,6 @@ #include "support/gettext.h" #include "support/lassert.h" #include "support/lstrings.h" // contains -#include "support/lyxalgo.h" #include "support/mutex.h" #include "support/ExceptionMessage.h" @@ -187,10 +182,10 @@ char_type replaceCommaInBraces(docstring & params) InsetInclude::InsetInclude(Buffer * buf, InsetCommandParams const & p) : InsetCommand(buf, p), include_label(uniqueID()), preview_(make_unique(this)), failedtoload_(false), - set_label_(false), label_(nullptr), child_buffer_(nullptr), file_exist_(false), + label_(nullptr), child_buffer_(nullptr), file_exist_(false), recursion_error_(false) { - preview_->connect([=](){ fileChanged(); }); + preview_->connect([this](){ fileChanged(); }); if (isListings(params())) { InsetListingsParams listing_params(to_utf8(p["lstparams"])); @@ -203,10 +198,10 @@ InsetInclude::InsetInclude(Buffer * buf, InsetCommandParams const & p) InsetInclude::InsetInclude(InsetInclude const & other) : InsetCommand(other), include_label(other.include_label), preview_(make_unique(this)), failedtoload_(false), - set_label_(false), label_(nullptr), child_buffer_(nullptr), + label_(nullptr), child_buffer_(nullptr), file_exist_(other.file_exist_),recursion_error_(other.recursion_error_) { - preview_->connect([=](){ fileChanged(); }); + preview_->connect([this](){ fileChanged(); }); if (other.label_) label_ = new InsetLabel(*other.label_); @@ -381,7 +376,6 @@ void InsetInclude::setParams(InsetCommandParams const & p) recursion_error_ = false; InsetCommand::setParams(p); - set_label_ = false; if (preview_->monitoring()) preview_->stopMonitoring(); @@ -405,7 +399,7 @@ bool InsetInclude::isChildIncluded() const docstring InsetInclude::screenLabel() const { - docstring pre = file_exist_ ? docstring() : _("FILE MISSING:"); + docstring pre = file_exist_ ? docstring() : _("MISSING:"); docstring temp; @@ -568,6 +562,16 @@ void InsetInclude::latex(otexstream & os, OutputParams const & runparams) const FileName const included_file = includedFileName(buffer(), params()); Buffer const * const masterBuffer = buffer().masterBuffer(); + if (runparams.inDeletedInset) { + // We cannot strike-out whole children, + // so we just output a note. + os << "\\textbf{" + << bformat(buffer().B_("[INCLUDED FILE %1$s DELETED!]"), + from_utf8(included_file.onlyFileName())) + << "}"; + return; + } + // if incfile is relative, make it relative to the master // buffer directory. if (!FileName::isAbsolute(incfile)) { @@ -614,9 +618,9 @@ void InsetInclude::latex(otexstream & os, OutputParams const & runparams) const FileName const writefile(makeAbsPath(mangled, runparams.for_preview ? buffer().temppath() : masterBuffer->temppath())); - LYXERR(Debug::LATEX, "incfile:" << incfile); - LYXERR(Debug::LATEX, "exportfile:" << exportfile); - LYXERR(Debug::LATEX, "writefile:" << writefile); + LYXERR(Debug::OUTFILE, "incfile:" << incfile); + LYXERR(Debug::OUTFILE, "exportfile:" << exportfile); + LYXERR(Debug::OUTFILE, "writefile:" << writefile); string const tex_format = flavor2format(runparams.flavor); @@ -779,7 +783,7 @@ void InsetInclude::latex(otexstream & os, OutputParams const & runparams) const if (checksum_in != checksum_out) { if (!included_file.copyTo(writefile)) { // FIXME UNICODE - LYXERR(Debug::LATEX, + LYXERR(Debug::OUTFILE, to_utf8(bformat(_("Could not copy the file\n%1$s\n" "into the temporary directory."), from_utf8(included_file.absFileName())))); @@ -987,12 +991,11 @@ docstring InsetInclude::xhtml(XMLStream & xs, OutputParams const & rp) const op.par_begin = 0; op.par_end = 0; ibuf->writeLyXHTMLSource(xs.os(), op, Buffer::IncludedFile); - } else - xs << XMLStream::ESCAPE_NONE - << ""; + } else { + xs << XMLStream::ESCAPE_NONE << ""; + } return docstring(); } @@ -1003,14 +1006,14 @@ int InsetInclude::plaintext(odocstringstream & os, { // just write the filename if we're making a tooltip or toc entry, // or are generating this for advanced search - if (op.for_tooltip || op.for_toc || op.for_search) { + if (op.for_tooltip || op.for_toc || op.find_effective()) { os << '[' << screenLabel() << '\n' << ltrim(getParam("filename")) << "\n]"; return PLAINTEXT_NEWLINE + 1; // one char on a separate line } if (isVerbatim(params()) || isListings(params())) { - if (op.for_search) { + if (op.find_effective()) { os << '[' << screenLabel() << ']'; } else { @@ -1037,56 +1040,80 @@ int InsetInclude::plaintext(odocstringstream & os, } -int InsetInclude::docbook(odocstream & os, OutputParams const & runparams) const +void InsetInclude::docbook(XMLStream & xs, OutputParams const & rp) const { - string incfile = ltrim(to_utf8(params()["filename"])); - - // Do nothing if no file name has been specified - if (incfile.empty()) - return 0; - - string const included_file = includedFileName(buffer(), params()).absFileName(); - string exppath = incfile; - if (!runparams.export_folder.empty()) { - exppath = makeAbsPath(exppath, runparams.export_folder).realPath(); - FileName(exppath).onlyPath().createPath(); - } + if (rp.inComment) + return; - // write it to a file (so far the complete file) - string const exportfile = changeExtension(exppath, ".sgml"); - DocFileName writefile(changeExtension(included_file, ".sgml")); + // For verbatim and listings, we just include the contents of the file as-is. + bool const verbatim = isVerbatim(params()); + bool const listing = isListings(params()); + if (listing || verbatim) { + if (listing) + xs << xml::StartTag("programlisting"); + else if (verbatim) + xs << xml::StartTag("literallayout"); - Buffer * tmp = loadIfNeeded(); - if (tmp) { - if (recursion_error_) - return 0; + // FIXME: We don't know the encoding of the file, default to UTF-8. + xs << includedFileName(buffer(), params()).fileContents("UTF-8"); - string const mangled = writefile.mangledFileName(); - writefile = makeAbsPath(mangled, - buffer().masterBuffer()->temppath()); - if (!runparams.nice) - incfile = mangled; + if (listing) + xs << xml::EndTag("programlisting"); + else if (verbatim) + xs << xml::EndTag("literallayout"); - LYXERR(Debug::LATEX, "incfile:" << incfile); - LYXERR(Debug::LATEX, "exportfile:" << exportfile); - LYXERR(Debug::LATEX, "writefile:" << writefile); + return; + } - tmp->makeDocBookFile(writefile, runparams, Buffer::OnlyBody); + // We don't know how to input or include non-LyX files. Input it as a comment. + FileName const included_file = includedFileName(buffer(), params()); + if (!isLyXFileName(included_file.absFileName())) { + if (!rp.silent) + frontend::Alert::warning(_("Unsupported Inclusion"), + bformat(_("LyX does not know how to process included non-LyX files when " + "generating DocBook output. The content of the file will be output as a " + "comment. Offending file:\n%1$s"), + ltrim(params()["filename"]))); + + // Read the file, output it wrapped into comments. + xs << XMLStream::ESCAPE_NONE << ""; + + xs << XMLStream::ESCAPE_NONE << ""; + + xs << XMLStream::ESCAPE_NONE << ""; } - runparams.exportdata->addExternalFile("docbook", writefile, - exportfile); - runparams.exportdata->addExternalFile("docbook-xml", writefile, - exportfile); + // In the other cases, we generate the DocBook version and include it. + Buffer const * const ibuf = loadIfNeeded(); + if (!ibuf) + return; - if (isVerbatim(params()) || isListings(params())) { - os << ""; - } else - os << '&' << include_label << ';'; + if (recursion_error_) + return; - return 0; + // are we generating only some paragraphs, or all of them? + bool const all_pars = !rp.dryrun || + (rp.par_begin == 0 && + rp.par_end == (int) buffer().text().paragraphs().size()); + + OutputParams op = rp; + if (all_pars) { + op.par_begin = 0; + op.par_end = 0; + op.inInclude = true; + op.docbook_in_par = false; + ibuf->writeDocBookSource(xs.os(), op, Buffer::IncludedFile); + } else { + xs << XMLStream::ESCAPE_NONE << ""; + } } @@ -1168,6 +1195,12 @@ void InsetInclude::collectBibKeys(InsetIterator const & /*di*/, FileNameList & c } +bool InsetInclude::inheritFont() const +{ + return !isVerbatim(params()); +} + + void InsetInclude::metrics(MetricsInfo & mi, Dimension & dim) const { LBUFERR(mi.base.bv); @@ -1182,15 +1215,9 @@ void InsetInclude::metrics(MetricsInfo & mi, Dimension & dim) const if (use_preview) { preview_->metrics(mi, dim); } else { - if (!set_label_) { - set_label_ = true; - button_.update(screenLabel(), true, false, !file_exist_ || recursion_error_); - } - button_.metrics(mi, dim); + setBroken(!file_exist_ || recursion_error_); + InsetCommand::metrics(mi, dim); } - - Box b(0, dim.wid, -dim.asc, dim.des); - button_.setBox(b); } @@ -1208,7 +1235,7 @@ void InsetInclude::draw(PainterInfo & pi, int x, int y) const if (use_preview) preview_->draw(pi, x, y); else - button_.draw(pi, x, y); + InsetCommand::draw(pi, x, y); } @@ -1224,7 +1251,7 @@ string InsetInclude::contextMenuName() const } -Inset::RowFlags InsetInclude::rowFlags() const +int InsetInclude::rowFlags() const { return type(params()) == INPUT ? Inline : Display; } @@ -1272,7 +1299,7 @@ docstring latexString(InsetInclude const & inset) // We don't need to set runparams.encoding since this will be done // by latex() anyway. OutputParams runparams(nullptr); - runparams.flavor = OutputParams::LATEX; + runparams.flavor = Flavor::LaTeX; runparams.for_preview = true; inset.latex(os, runparams); @@ -1286,7 +1313,19 @@ void add_preview(RenderMonitoredPreview & renderer, InsetInclude const & inset, InsetCommandParams const & params = inset.params(); if (RenderPreview::previewText() && preview_wanted(params, buffer)) { renderer.setAbsFile(includedFileName(buffer, params)); - docstring const snippet = latexString(inset); + docstring snippet; + try { + // InsetInclude::latex() throws if generation of LaTeX + // fails, e.g. if lyx2lyx fails because file is too + // new, or knitr fails. + snippet = latexString(inset); + } catch (...) { + // remove current preview because it is likely + // associated with the previous included file name + renderer.removePreview(buffer); + LYXERR0("Preview of include failed."); + return; + } renderer.addPreview(snippet, buffer); } } @@ -1317,39 +1356,44 @@ void InsetInclude::addToToc(DocIterator const & cpit, bool output_active, InsetListingsParams p(to_utf8(params()["lstparams"])); b.argumentItem(from_utf8(p.getParamValue("caption"))); b.pop(); - } else if (isVerbatim(params())) { + return; + } + if (isVerbatim(params())) { TocBuilder & b = backend.builder("child"); b.pushItem(cpit, screenLabel(), output_active); b.pop(); - } else { - Buffer const * const childbuffer = loadIfNeeded(); + return; + } + // the common case + Buffer const * const childbuffer = loadIfNeeded(); - TocBuilder & b = backend.builder("child"); - docstring str = childbuffer ? childbuffer->fileName().displayName() - : from_ascii("?"); - b.pushItem(cpit, str, output_active); - b.pop(); + TocBuilder & b = backend.builder("child"); + string const fname = ltrim(to_utf8(params()["filename"])); + // mark non-existent file with MISSING + docstring const str = (file_exist_ ? from_ascii("") : _("MISSING: ")) + + from_utf8(onlyFileName(fname)) + " (" + from_utf8(fname) + ")"; + b.pushItem(cpit, str, output_active); + b.pop(); - if (!childbuffer) - return; + if (!childbuffer) + return; - if (checkForRecursiveInclude(childbuffer)) - return; - buffer().pushIncludedBuffer(childbuffer); - // Update the child's tocBackend. The outliner uses the master's, but - // the navigation menu uses the child's. - childbuffer->tocBackend().update(output_active, utype); - // Include Tocs from children - childbuffer->inset().addToToc(DocIterator(), output_active, utype, - backend); - buffer().popIncludedBuffer(); - // Copy missing outliner names (though the user has been warned against - // having different document class and module selection between master - // and child). - for (auto const & name - : childbuffer->params().documentClass().outlinerNames()) - backend.addName(name.first, translateIfPossible(name.second)); - } + if (checkForRecursiveInclude(childbuffer)) + return; + buffer().pushIncludedBuffer(childbuffer); + // Update the child's tocBackend. The outliner uses the master's, but + // the navigation menu uses the child's. + childbuffer->tocBackend().update(output_active, utype); + // Include Tocs from children + childbuffer->inset().addToToc(DocIterator(), output_active, utype, + backend); + buffer().popIncludedBuffer(); + // Copy missing outliner names (though the user has been warned against + // having different document class and module selection between master + // and child). + for (auto const & name + : childbuffer->params().documentClass().outlinerNames()) + backend.addName(name.first, translateIfPossible(name.second)); } @@ -1382,12 +1426,9 @@ void InsetInclude::updateBuffer(ParIterator const & it, UpdateType utype, bool c if (childbuffer) { if (!checkForRecursiveInclude(childbuffer)) childbuffer->updateBuffer(Buffer::UpdateChildOnly, utype); - button_.update(screenLabel(), true, false, recursion_error_); return; } - button_.update(screenLabel(), true, false, !file_exist_); - if (!isListings(params())) return;