return VERB;
if (s == "verbatiminput*")
return VERBAST;
- if (s == "lstinputlisting")
+ if (s == "lstinputlisting" || s == "inputminted")
return LISTINGS;
if (s == "include")
return INCLUDE;
InsetInclude::InsetInclude(Buffer * buf, InsetCommandParams const & p)
: InsetCommand(buf, p), include_label(uniqueID()),
- preview_(new RenderMonitoredPreview(this)), failedtoload_(false),
+ preview_(make_unique<RenderMonitoredPreview>(this)), failedtoload_(false),
set_label_(false), label_(0), child_buffer_(0)
{
- preview_->fileChanged(bind(&InsetInclude::fileChanged, this));
+ preview_->connect([=](){ fileChanged(); });
if (isListings(params())) {
InsetListingsParams listing_params(to_utf8(p["lstparams"]));
InsetInclude::InsetInclude(InsetInclude const & other)
: InsetCommand(other), include_label(other.include_label),
- preview_(new RenderMonitoredPreview(this)), failedtoload_(false),
+ preview_(make_unique<RenderMonitoredPreview>(this)), failedtoload_(false),
set_label_(false), label_(0), child_buffer_(0)
{
- preview_->fileChanged(bind(&InsetInclude::fileChanged, this));
+ preview_->connect([=](){ fileChanged(); });
if (other.label_)
label_ = new InsetLabel(*other.label_);
InsetInclude::~InsetInclude()
{
if (isBufferLoaded())
- buffer().invalidateBibfileCache();
+ /* We do not use buffer() because Coverity believes that this
+ * may throw an exception. Actually this code path is not
+ * taken when buffer_ == 0 */
+ buffer_->invalidateBibfileCache();
delete label_;
}
lyx::dispatch(fr);
} else
// tex file or other text file in verbatim mode
- formats.edit(buffer(),
+ theFormats().edit(buffer(),
support::makeAbsPath(file, support::onlyPath(buffer().absFileName())),
"text");
}
break;
}
case LISTINGS: {
+ // Here, listings and minted have sligthly different behaviors.
+ // Using listings, it is always possible to have a caption,
+ // even for non-floats. Using minted, only floats can have a
+ // caption. So, with minted we use the following strategy.
+ // If a caption was specified but the float parameter was not,
+ // we ourselves add a caption above the listing (because the
+ // listing comes from a file and might span several pages).
+ // Otherwise, if float was specified, the floating listing
+ // environment provided by minted is used. In either case, the
+ // label parameter is taken as the label by which the float
+ // can be referenced, otherwise it will have the meaning
+ // intended by minted. In this last case, the label will
+ // serve as a sort of caption that, however, will be shown
+ // by minted only if the frame parameter is also specified.
+ bool const use_minted = buffer().params().use_minted;
runparams.exportdata->addExternalFile(tex_format, writefile,
exportfile);
- os << '\\' << from_ascii(params().getCmdName());
string const opt = to_utf8(params()["lstparams"]);
// opt is set in QInclude dialog and should have passed validation.
- InsetListingsParams params(opt);
- if (!params.params().empty())
- os << "[" << from_utf8(params.params()) << "]";
- os << '{' << from_utf8(incfile) << '}';
+ InsetListingsParams lstparams(opt);
+ string parameters = lstparams.params();
+ string language;
+ string caption;
+ string label;
+ string placement;
+ bool isfloat = lstparams.isFloat();
+ if (use_minted) {
+ // Get float placement, language, caption, and
+ // label, then remove the relative options.
+ vector<string> opts =
+ getVectorFromString(parameters, ",", false);
+ for (size_t i = 0; i < opts.size(); ++i) {
+ if (prefixIs(opts[i], "float")) {
+ if (prefixIs(opts[i], "float="))
+ placement = opts[i].substr(6);
+ opts.erase(opts.begin() + i--);
+ } else if (prefixIs(opts[i], "language=")) {
+ language = opts[i].substr(9);
+ opts.erase(opts.begin() + i--);
+ } else if (prefixIs(opts[i], "caption=")) {
+ caption = opts[i].substr(8);
+ opts.erase(opts.begin() + i--);
+ } else if (prefixIs(opts[i], "label=")) {
+ label = opts[i].substr(6);
+ opts.erase(opts.begin() + i--);
+ }
+ }
+ if (!label.empty()) {
+ if (isfloat || !caption.empty())
+ label = trim(label, "{}");
+ else
+ opts.push_back("label=" + label);
+ }
+ parameters = getStringFromVector(opts, ",");
+ }
+ if (language.empty())
+ language = "TeX";
+ if (use_minted && isfloat) {
+ os << breakln << "\\begin{listing}";
+ if (!placement.empty())
+ os << '[' << placement << "]";
+ os << breakln;
+ } else if (use_minted && !caption.empty()) {
+ os << breakln << "\\lyxmintcaption[t]{" << caption;
+ if (!label.empty())
+ os << "\\label{" << label << "}";
+ os << "}\n";
+ }
+ os << (use_minted ? "\\inputminted" : "\\lstinputlisting");
+ if (!parameters.empty())
+ os << "[" << parameters << "]";
+ if (use_minted)
+ os << '{' << ascii_lowercase(language) << '}';
+ os << '{' << incfile << '}';
+ if (use_minted && isfloat) {
+ if (!caption.empty())
+ os << breakln << "\\caption{" << caption << "}";
+ if (!label.empty())
+ os << breakln << "\\label{" << label << "}";
+ os << breakln << "\\end{listing}\n";
+ }
break;
}
case INCLUDE: {
"file\n`%1$s'\n"
"Please, check whether it actually exists."),
included_file.displayName());
- Alert::warning(_("Missing included file"), text);
+ throw ExceptionMessage(ErrorException, _("Error: "),
+ text);
}
return;
}
// Don't assume the child's format is latex
string const inc_format = tmp->params().bufferFormat();
FileName const tmpwritefile(changeExtension(writefile.absFileName(),
- formats.extension(inc_format)));
+ theFormats().extension(inc_format)));
// FIXME: handle non existing files
// The included file might be written in a different encoding
features.useInsetLayout(getLayout());
if (isVerbatim(params()))
features.require("verbatim");
- else if (isListings(params()))
- features.require("listings");
+ else if (isListings(params())) {
+ if (buffer().params().use_minted) {
+ features.require("minted");
+ string const opts = to_utf8(params()["lstparams"]);
+ InsetListingsParams lstpars(opts);
+ if (!lstpars.isFloat() && contains(opts, "caption="))
+ features.require("lyxmintcaption");
+ } else
+ features.require("listings");
+ }
// Here we must do the fun stuff...
// Load the file in the include if it needs
} else {
if (!set_label_) {
set_label_ = true;
- button_.update(screenLabel(), true);
+ button_.update(screenLabel(), true, false);
}
button_.metrics(mi, dim);
}
if (!childbuffer)
return;
+ // 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);
void InsetInclude::updateBuffer(ParIterator const & it, UpdateType utype)
{
- button_.update(screenLabel(), true);
+ button_.update(screenLabel(), true, false);
Buffer const * const childbuffer = getChildBuffer();
if (childbuffer) {