From 8fa0e539e52512b80c5c3eac965e3abb98ba484e Mon Sep 17 00:00:00 2001 From: Enrico Forestieri Date: Thu, 8 Jun 2017 19:33:54 +0200 Subject: [PATCH] Extend minted support to listings as child documents This was slipping through the cracks, apparently... --- src/frontends/qt4/GuiInclude.cpp | 15 ++++-- src/insets/InsetInclude.cpp | 78 +++++++++++++++++++++++++++--- src/insets/InsetListingsParams.cpp | 13 ++--- 3 files changed, 88 insertions(+), 18 deletions(-) diff --git a/src/frontends/qt4/GuiInclude.cpp b/src/frontends/qt4/GuiInclude.cpp index b02fd9181f..78c62031ca 100644 --- a/src/frontends/qt4/GuiInclude.cpp +++ b/src/frontends/qt4/GuiInclude.cpp @@ -15,6 +15,7 @@ #include "GuiInclude.h" #include "Buffer.h" +#include "BufferParams.h" #include "FuncRequest.h" #include "LyXRC.h" @@ -94,7 +95,9 @@ docstring GuiInclude::validate_listings_params() if (typeCO->currentIndex() != 3 || bypassCB->isChecked()) return docstring(); string params = fromqstr(listingsED->toPlainText()); - return InsetListingsParams(params).validate(); + InsetListingsParams lstparams(params); + lstparams.setMinted(buffer().params().use_minted); + return lstparams.validate(); } @@ -176,7 +179,8 @@ void GuiInclude::paramsToDialog(InsetCommandParams const & params_) if (cmdname != "include" && cmdname != "verbatiminput" && cmdname != "verbatiminput*" && - cmdname != "lstinputlisting") + cmdname != "lstinputlisting" && + cmdname != "inputminted") cmdname = "input"; if (cmdname == "include") { @@ -196,7 +200,7 @@ void GuiInclude::paramsToDialog(InsetCommandParams const & params_) typeCO->setCurrentIndex(2); visiblespaceCB->setEnabled(true); - } else if (cmdname == "lstinputlisting") { + } else if (cmdname == "lstinputlisting" || cmdname == "inputminted") { typeCO->setCurrentIndex(3); listingsGB->setEnabled(true); listingsED->setEnabled(true); @@ -241,7 +245,10 @@ void GuiInclude::applyView() } else if (item == 1) { params_.setCmdName("input"); } else if (item == 3) { - params_.setCmdName("lstinputlisting"); + if (buffer().params().use_minted) + params_.setCmdName("inputminted"); + else + params_.setCmdName("lstinputlisting"); // the parameter string should have passed validation InsetListingsParams par(fromqstr(listingsED->toPlainText())); string caption = fromqstr(captionLE->text()); diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index 3ae1b48965..6ae77a657c 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -99,7 +99,7 @@ Types type(string const & s) return VERB; if (s == "verbatiminput*") return VERBAST; - if (s == "lstinputlisting") + if (s == "lstinputlisting" || s == "inputminted") return LISTINGS; if (s == "include") return INCLUDE; @@ -598,15 +598,81 @@ void InsetInclude::latex(otexstream & os, OutputParams const & runparams) const 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 or the float parameter are specified, we + // assume that the listing is floating. In this 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 = false; + if (use_minted) { + // Get float placement, language, caption, and + // label, then remove the relative options. + vector opts = + getVectorFromString(parameters, ",", false); + for (size_t i = 0; i < opts.size(); ++i) { + if (prefixIs(opts[i], "float")) { + isfloat = true; + 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=")) { + isfloat = true; + 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) + 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; + } + os << (use_minted ? "\\inputminted" : "\\lstinputlisting"); + if (!parameters.empty()) + os << "[" << parameters << "]"; + if (use_minted) + os << '{' << 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: { diff --git a/src/insets/InsetListingsParams.cpp b/src/insets/InsetListingsParams.cpp index bab238ae1e..a2d2cea3c7 100644 --- a/src/insets/InsetListingsParams.cpp +++ b/src/insets/InsetListingsParams.cpp @@ -687,7 +687,7 @@ ParValidator::ParValidator() all_params_[1]["autogobble"] = ListingsParam("", true, TRUEFALSE, "", empty_hint); all_params_[1]["baselinestretch"] = - ListingsParam("", false, LENGTH, "", empty_hint); + ListingsParam("", false, ALL, "", empty_hint); all_params_[1]["breakafter"] = ListingsParam("", false, ALL, "", empty_hint); all_params_[1]["breakaftergroup"] = @@ -791,15 +791,12 @@ ParValidator::ParValidator() all_params_[1]["labelposition"] = ListingsParam("", false, ONEOF, "none\ntopline\nbottomline\nall", empty_hint); - all_params_[1]["language"] = - ListingsParam("", false, ONEOF, - allowed_languages, empty_hint); all_params_[1]["language"] = ListingsParam("", false, ALL, "", _( - "This parameter should not be entered here. Please " - "use the language combo box in the listings inset " - "settings dialog, unless you need to enter a language " - "not offered there.")); + "Enter one of the supported languages. However, if you " + "are defining a listing inset, it is better using the " + "language combo box, unless you need to enter a language not " + "offered there, otherwise the combo box will be disabled.")); all_params_[1]["lastline"] = ListingsParam("", false, INTEGER, "", empty_hint); all_params_[1]["linenos"] = -- 2.39.2