From 8dab1cfe7ee6a3bb6d5e57afb55cb357e1e8ec23 Mon Sep 17 00:00:00 2001 From: Enrico Forestieri Date: Wed, 7 Jun 2017 00:55:23 +0200 Subject: [PATCH] Fix bug #9101 Update the listings inset to optionally use the minted package (instead of the listings one) for typesetting code listings. Only one of the two packages can be used in a document, but it is possible to switch packages without issues if the used options are the same. If a switch is made and the options differ, one needs to manually adjust them if they were entered in the advanced options tab, or apply again the gui settings. Note that minted requires the -shell-escape option for the latex backend and the installation of additional software (python pygments). --- development/FORMAT | 5 + lib/layouts/stdinsets.inc | 34 +- lib/lyx2lyx/lyx_2_3.py | 16 +- lib/syntax.default | 3 + src/BufferParams.cpp | 22 +- src/BufferParams.h | 2 + src/LaTeXFeatures.cpp | 8 +- src/LaTeXFeatures.h | 3 +- src/frontends/qt4/GuiDocument.cpp | 5 + src/frontends/qt4/GuiListings.cpp | 80 ++- src/frontends/qt4/ui/ListingsSettingsUi.ui | 76 +-- src/insets/InsetCommand.cpp | 9 +- src/insets/InsetInclude.cpp | 8 +- src/insets/InsetListings.cpp | 76 ++- src/insets/InsetListingsParams.cpp | 592 +++++++++++++----- src/insets/InsetListingsParams.h | 9 + src/insets/InsetTOC.cpp | 8 +- src/tex2lyx/TODO.txt | 13 + src/tex2lyx/test/CJK.lyx.lyx | 2 +- src/tex2lyx/test/CJKutf8.lyx.lyx | 2 +- src/tex2lyx/test/DummyDocument.lyx.lyx | 2 +- src/tex2lyx/test/Dummy~Document.lyx.lyx | 2 +- src/tex2lyx/test/XeTeX-polyglossia.lyx.lyx | 2 +- src/tex2lyx/test/algo2e.lyx.lyx | 2 +- .../test/box-color-size-space-align.lyx.lyx | 2 +- src/tex2lyx/test/test-insets-basic.lyx.lyx | 2 +- src/tex2lyx/test/test-insets.lyx.lyx | 2 +- src/tex2lyx/test/test-memoir.lyx.lyx | 2 +- src/tex2lyx/test/test-modules.lyx.lyx | 2 +- .../test/test-refstyle-theorems.lyx.lyx | 2 +- src/tex2lyx/test/test-scr.lyx.lyx | 2 +- src/tex2lyx/test/test-structure.lyx.lyx | 2 +- src/tex2lyx/test/test.lyx.lyx | 2 +- src/tex2lyx/test/verbatim.lyx.lyx | 2 +- src/version.h | 4 +- 35 files changed, 735 insertions(+), 270 deletions(-) diff --git a/development/FORMAT b/development/FORMAT index 8b28a8aa18..7477ae9bfb 100644 --- a/development/FORMAT +++ b/development/FORMAT @@ -7,6 +7,11 @@ changes happened in particular if possible. A good example would be ----------------------- +2017-06-06 Enrico Forestieri + * Format incremented to 544: support for minted. + The listings inset now supports also the minted package. + - New buffer param \use_minted {true|false} + 2017-05-13 Uwe Stöhr * Format incremented to 543: rename buffer parameter math_number_before to math_numbering_side diff --git a/lib/layouts/stdinsets.inc b/lib/layouts/stdinsets.inc index 981feb056c..1ef2c524b7 100644 --- a/lib/layouts/stdinsets.inc +++ b/lib/layouts/stdinsets.inc @@ -274,16 +274,21 @@ InsetLayout TOC:Listings # We need the [[List of Listings]] context, since "Listings" is also # the name of the inset and translated differently. # "Listings[[List of Listings]]" is the name of the "List of listings" - # ("Listings" is the predefined english name) in listings.sty, so it - # must be used here as well. + # ("Listings" is the predefined english name) in listings.sty and + # minted.sty, so it must be used here as well. BabelPreamble - \addto\captions$$lang{\renewcommand{\lstlistlistingname}{_(Listings[[List of Listings]])}} + \ifx\minted\undefined + \addto\captions$$lang{\renewcommand{\lstlistlistingname}{_(Listings[[List of Listings]])}}\else + \addto\captions$$lang{\renewcommand{\listoflistingscaption}{_(Listings[[List of Listings]])}}\fi EndBabelPreamble - # The command does not need to be defined in LangPreamble, since - # listings.sty does that already. However it needs to be redefined - # in order to be used for non-english single-language documents. + # Either commands do not need to be defined in LangPreamble, since + # listings.sty or minted.sty do that already. However they need to be + # redefined in order to be used for non-english single-language + # documents. LangPreamble - \renewcommand{\lstlistlistingname}{_(Listings[[List of Listings]])} + \ifx\minted\undefined + \renewcommand{\lstlistlistingname}{_(Listings[[List of Listings]])}\else + \renewcommand{\listoflistingscaption}{_(Listings[[List of Listings]])}\fi EndLangPreamble FixedWidthPreambleEncoding true HTMLTag h2 @@ -298,13 +303,18 @@ End InsetLayout Include:Listings BabelPreamble - \addto\captions$$lang{\renewcommand{\lstlistingname}{_(Listing)}} + \ifx\minted\undefined + \addto\captions$$lang{\renewcommand{\lstlistingname}{_(Listing)}}\else + \addto\captions$$lang{\renewcommand{\listingscaption}{_(Listing)}}\fi EndBabelPreamble - # The command does not need to be defined in LangPreamble, since - # listings.sty does that already. However it needs to be redefined - # in order to be used for non-english single-language documents. + # Either commands do not need to be defined in LangPreamble, since + # listings.sty or minted.sty do that already. However they need to be + # redefined in order to be used for non-english single-language + # documents. LangPreamble - \renewcommand{\lstlistingname}{_(Listing)} + \ifx\minted\undefined + \renewcommand{\lstlistingname}{_(Listing)}\else + \renewcommand{\listingscaption}{_(Listing)}\fi EndLangPreamble FixedWidthPreambleEncoding true End diff --git a/lib/lyx2lyx/lyx_2_3.py b/lib/lyx2lyx/lyx_2_3.py index cda390dc01..73ac45cf00 100644 --- a/lib/lyx2lyx/lyx_2_3.py +++ b/lib/lyx2lyx/lyx_2_3.py @@ -2234,6 +2234,18 @@ def revert_mathnumberingname(document): document.header[i] = "\\math_number_before 0" +def convert_minted(document): + " add the \\use_minted tag " + document.header.insert(-1, "\\use_minted 0") + + +def revert_minted(document): + " remove the \\use_minted tag " + i = find_token(document.header, "\\use_minted", 0) + if i != -1: + document.header.pop(i) + + ## # Conversion hub # @@ -2274,10 +2286,12 @@ convert = [ [540, []], [541, [convert_allowbreak]], [542, [convert_mathnumberpos]], - [543, [convert_mathnumberingname]] + [543, [convert_mathnumberingname]], + [544, [convert_minted]] ] revert = [ + [543, [revert_minted]], [542, [revert_mathnumberingname]], [541, [revert_mathnumberpos]], [540, [revert_allowbreak]], diff --git a/lib/syntax.default b/lib/syntax.default index 924dbe4fae..d9596b6f86 100644 --- a/lib/syntax.default +++ b/lib/syntax.default @@ -142,6 +142,7 @@ $$ \Large \LARGE \marginpar[]{} +\mintinline[,]{} \multicolumn{}{}{} \newline \noindent @@ -712,6 +713,8 @@ $$ % LaTeX code that can be translated to LyX. \begin{environments} bibunit[]{translate} +listing{} % minted.sty +minted{} % minted.sty psmatrix[]{} subfigure[]{translate} % subcaption.sty subtable[]{translate} % subcaption.sty diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 5522c705a0..24aaf02c51 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -461,6 +461,7 @@ BufferParams::BufferParams() output_sync = false; use_refstyle = true; + use_minted = false; // map current author author_map_[pimpl_->authorlist.get(0).bufferId()] = 0; @@ -1095,6 +1096,8 @@ string BufferParams::readToken(Lexer & lex, string const & token, lex >> output_sync_macro; } else if (token == "\\use_refstyle") { lex >> use_refstyle; + } else if (token == "\\use_minted") { + lex >> use_minted; } else { lyxerr << "BufferParams::readToken(): Unknown token: " << token << endl; @@ -1302,6 +1305,7 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const << "\n\\suppress_date " << convert(suppress_date) << "\n\\justification " << convert(justification) << "\n\\use_refstyle " << use_refstyle + << "\n\\use_minted " << use_minted << '\n'; if (isbackgroundcolor == true) os << "\\backgroundcolor " << lyx::X11hexname(backgroundcolor) << '\n'; @@ -2253,10 +2257,19 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, } if (features.isRequired("bicaption")) os << "\\usepackage{bicaption}\n"; - if (!listings_params.empty() || features.mustProvide("listings")) - os << "\\usepackage{listings}\n"; + if (!listings_params.empty() + || features.mustProvide("listings") + || features.mustProvide("minted")) { + if (features.mustProvide("listings")) + os << "\\usepackage{listings}\n"; + else + os << "\\usepackage{minted}\n"; + } if (!listings_params.empty()) { - os << "\\lstset{"; + if (features.mustProvide("listings")) + os << "\\lstset{"; + else + os << "\\setminted{"; // do not test validity because listings_params is // supposed to be valid string par = @@ -2353,7 +2366,8 @@ bool BufferParams::writeLaTeX(otexstream & os, LaTeXFeatures & features, } docstring const i18npreamble = - features.getTClassI18nPreamble(use_babel, use_polyglossia); + features.getTClassI18nPreamble(use_babel, use_polyglossia, + use_minted); if (!i18npreamble.empty()) os << i18npreamble + '\n'; diff --git a/src/BufferParams.h b/src/BufferParams.h index e99238692d..9f20ce14c6 100644 --- a/src/BufferParams.h +++ b/src/BufferParams.h @@ -541,6 +541,8 @@ public: std::string output_sync_macro; /// use refstyle? or prettyref? bool use_refstyle; + /// use minted? or listings? + bool use_minted; /// Return true if language could be set to lang, /// otherwise return false and do not change language diff --git a/src/LaTeXFeatures.cpp b/src/LaTeXFeatures.cpp index 55db953503..b10a9a2754 100644 --- a/src/LaTeXFeatures.cpp +++ b/src/LaTeXFeatures.cpp @@ -1757,7 +1757,8 @@ docstring const i18npreamble(docstring const & templ, Language const * lang, } -docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel, bool use_polyglossia) const +docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel, + bool use_polyglossia, bool use_minted) const { DocumentClass const & tclass = params_.documentClass(); // collect preamble snippets in a set to prevent multiple identical @@ -1839,8 +1840,9 @@ docstring const LaTeXFeatures::getTClassI18nPreamble(bool use_babel, bool use_po // need to force a fixed width encoding for // \lstlistlistingname and \lstlistingname (bug 9382). // This needs to be consistent with InsetListings::latex(). - bool const need_fixedwidth = !runparams_.isFullUnicode() && - it->second.fixedwidthpreambleencoding(); + bool const need_fixedwidth = !use_minted && + !runparams_.isFullUnicode() && + it->second.fixedwidthpreambleencoding(); // language dependent commands (once per document) snippets.insert(i18npreamble(it->second.langpreamble(), buffer().language(), diff --git a/src/LaTeXFeatures.h b/src/LaTeXFeatures.h index 06d2ee99ad..df071c671b 100644 --- a/src/LaTeXFeatures.h +++ b/src/LaTeXFeatures.h @@ -73,7 +73,8 @@ public: /// The definitions needed by the document's textclass docstring const getTClassPreamble() const; /// The language dependent definitions needed by the document's textclass - docstring const getTClassI18nPreamble(bool use_babel, bool use_polyglossia) const; + docstring const getTClassI18nPreamble(bool use_babel, + bool use_polyglossia, bool use_minted) const; /// docstring const getTClassHTMLStyles() const; /// diff --git a/src/frontends/qt4/GuiDocument.cpp b/src/frontends/qt4/GuiDocument.cpp index cc082ad0ee..cba3f3e025 100644 --- a/src/frontends/qt4/GuiDocument.cpp +++ b/src/frontends/qt4/GuiDocument.cpp @@ -1461,6 +1461,8 @@ GuiDocument::GuiDocument(GuiView & lv) this, SLOT(change_adaptor())); connect(listingsModule->bypassCB, SIGNAL(clicked()), this, SLOT(setListingsMessage())); + connect(listingsModule->mintedCB, SIGNAL(clicked()), + this, SLOT(change_adaptor())); connect(listingsModule->listingsED, SIGNAL(textChanged()), this, SLOT(setListingsMessage())); listingsModule->listingsTB->setPlainText( @@ -3070,6 +3072,7 @@ void GuiDocument::applyView() // Listings // text should have passed validation + bp_.use_minted = listingsModule->mintedCB->isChecked(); bp_.listings_params = InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params(); @@ -3587,6 +3590,8 @@ void GuiDocument::paramsToDialog() string lstparams = InsetListingsParams(bp_.listings_params).separatedParams(); listingsModule->listingsED->setPlainText(toqstr(lstparams)); + listingsModule->mintedCB->setChecked(bp_.use_minted); + // Fonts // some languages only work with polyglossia/XeTeX diff --git a/src/frontends/qt4/GuiListings.cpp b/src/frontends/qt4/GuiListings.cpp index bc7fdb8176..561022f595 100644 --- a/src/frontends/qt4/GuiListings.cpp +++ b/src/frontends/qt4/GuiListings.cpp @@ -15,6 +15,8 @@ #include "qt_helpers.h" +#include "Buffer.h" +#include "BufferParams.h" #include "FuncRequest.h" #include "insets/InsetListings.h" @@ -293,10 +295,20 @@ string GuiListings::construct_params() string fontsize = font_sizes[qMax(0, fontsizeCO->currentIndex())]; string fontstyle = font_styles[qMax(0, fontstyleCO->currentIndex())]; string basicstyle; - if (fontsize != "default") - basicstyle = "\\" + fontsize; - if (fontstyle != "default") - basicstyle += "\\" + fontstyle; + string mintedsize; + bool const use_minted = buffer().params().use_minted; + if (fontsize != "default") { + if (use_minted) + mintedsize = "\\" + fontsize; + else + basicstyle = "\\" + fontsize; + } + if (fontstyle != "default") { + if (use_minted) + basicstyle = fontstyle.substr(0, 2); + else + basicstyle += "\\" + fontstyle; + } bool breakline = breaklinesCB->isChecked(); bool space = spaceCB->isChecked(); int tabsize = tabsizeSB->value(); @@ -306,7 +318,13 @@ string GuiListings::construct_params() // compose a string InsetListingsParams par; - if (language != "no language" && !contains(extra, "language=")) { + par.setMinted(use_minted); + if (use_minted) { + if (language == "no language" && !contains(extra, "language=")) + par.addParam("language", "TeX"); + else + par.addParam("language", language); + } else if (language != "no language" && !contains(extra, "language=")) { if (dialect.empty()) par.addParam("language", language); else @@ -319,7 +337,7 @@ string GuiListings::construct_params() par.addParam("float", placement); if (numberSide != "none") par.addParam("numbers", numberSide); - if (numberfontsize != "default" && numberSide != "none") + if (numberfontsize != "default" && numberSide != "none" && !use_minted) par.addParam("numberstyle", "\\" + numberfontsize); if (!stepnumber.empty() && numberSide != "none") par.addParam("stepnumber", stepnumber); @@ -328,16 +346,18 @@ string GuiListings::construct_params() if (!lastline.empty()) par.addParam("lastline", lastline); if (!basicstyle.empty()) - par.addParam("basicstyle", basicstyle); + par.addParam(use_minted ? "fontfamily" : "basicstyle", basicstyle); + if (!mintedsize.empty()) + par.addParam("fontsize", mintedsize); if (breakline) par.addParam("breaklines", "true"); if (space) par.addParam("showspaces", "true"); - if (!spaceInString) + if (!spaceInString && !use_minted) par.addParam("showstringspaces", "false"); if (tabsize != 8) par.addParam("tabsize", convert(tabsize)); - if (extendedchars) + if (extendedchars && !use_minted) par.addParam("extendedchars", "true"); par.addParams(extra); return par.params(); @@ -419,6 +439,7 @@ void GuiListings::on_languageCO_currentIndexChanged(int index) void GuiListings::applyView() { + params_.setMinted(buffer().params().use_minted); params_.setInline(inlineCB->isChecked()); params_.setParams(construct_params()); } @@ -435,6 +456,7 @@ static string plainParam(string const & par) void GuiListings::updateContents() { + bool const use_minted = buffer().params().use_minted; // set default values listingsTB->setPlainText( qt_("Input listing parameters on the right. Enter ? for a list of parameters.")); @@ -503,7 +525,7 @@ void GuiListings::updateContents() if (in_gui) *it = ""; languageCO->setEnabled(in_gui); - dialectCO->setEnabled( + dialectCO->setEnabled(!use_minted && in_gui && dialectCO->count() > 1); } else if (prefixIs(*it, "float")) { floatCB->setChecked(true); @@ -571,6 +593,36 @@ void GuiListings::updateContents() } *it = ""; } + } else if (prefixIs(*it, "fontsize=")) { + string size; + for (int n = 0; font_sizes[n][0]; ++n) { + string const s = font_sizes[n]; + if (contains(*it, "\\" + s)) { + size = "\\" + s; + break; + } + } + if (!size.empty()) { + int n = findToken(font_sizes, size.substr(1)); + if (n >= 0) + fontsizeCO->setCurrentIndex(n); + } + *it = ""; + } else if (prefixIs(*it, "fontfamily=")) { + string style; + for (int n = 0; font_styles[n][0]; ++n) { + string const s = font_styles[n]; + if (contains(*it, "=" + s.substr(0,2))) { + style = "\\" + s; + break; + } + } + if (!style.empty()) { + int n = findToken(font_styles, style.substr(1)); + if (n >= 0) + fontstyleCO->setCurrentIndex(n); + } + *it = ""; } else if (prefixIs(*it, "breaklines=")) { breaklinesCB->setChecked(contains(*it, "true")); *it = ""; @@ -590,11 +642,15 @@ void GuiListings::updateContents() } numberStepLE->setEnabled(numberSideCO->currentIndex() > 0); - numberFontSizeCO->setEnabled(numberSideCO->currentIndex() > 0); + numberFontSizeCO->setEnabled(numberSideCO->currentIndex() > 0 + && !use_minted); + spaceInStringCB->setEnabled(!use_minted); + extendedcharsCB->setEnabled(!use_minted); // parameters that can be handled by widgets are cleared // the rest is put to the extra edit box. string extra = getStringFromVector(pars); listingsED->setPlainText(toqstr(InsetListingsParams(extra).separatedParams())); + params_.setMinted(use_minted); } @@ -614,6 +670,7 @@ bool GuiListings::initialiseParams(string const & data) void GuiListings::clearParams() { params_.clear(); + params_.setMinted(buffer().params().use_minted); } @@ -627,6 +684,7 @@ void GuiListings::dispatchParams() void GuiListings::setParams(InsetListingsParams const & params) { params_ = params; + params_.setMinted(buffer().params().use_minted); } diff --git a/src/frontends/qt4/ui/ListingsSettingsUi.ui b/src/frontends/qt4/ui/ListingsSettingsUi.ui index 3a1b1ce2fb..ec26f0d138 100644 --- a/src/frontends/qt4/ui/ListingsSettingsUi.ui +++ b/src/frontends/qt4/ui/ListingsSettingsUi.ui @@ -1,33 +1,33 @@ - + ListingsSettingsUi - - + + 0 0 219 - 185 + 256 - + - - + + 9 - + 6 - + - + Qt::Vertical - + QSizePolicy::Expanding - + 201 21 @@ -35,54 +35,60 @@ - - - - - 7 - 5 + + + + 0 0 - + Input here the listings parameters - - - - - 7 - 5 + + + + 0 0 - + false - + Feedback window - + QFrame::Box - + QFrame::Plain - + false - - - + + + + Use the minted package instead of the listings one + + + Use minted + + + + + + Check it to enter parameters that are not recognizable by LyX - + &Bypass validation @@ -90,7 +96,7 @@ - qt_i18n.h + qt_i18n.h diff --git a/src/insets/InsetCommand.cpp b/src/insets/InsetCommand.cpp index fe10466e23..5043386165 100644 --- a/src/insets/InsetCommand.cpp +++ b/src/insets/InsetCommand.cpp @@ -15,6 +15,7 @@ #include "Buffer.h" #include "BufferEncodings.h" +#include "BufferParams.h" #include "BufferView.h" #include "Cursor.h" #include "DispatchResult.h" @@ -43,12 +44,14 @@ #include "support/debug.h" #include "support/gettext.h" +#include "support/lstrings.h" #include "frontends/Application.h" #include using namespace std; +using namespace lyx::support; namespace lyx { @@ -139,7 +142,11 @@ void InsetCommand::setParams(InsetCommandParams const & p) void InsetCommand::latex(otexstream & os, OutputParams const & runparams_in) const { OutputParams runparams = runparams_in; - os << getCommand(runparams); + docstring command = getCommand(runparams); + if (buffer().params().use_minted + && prefixIs(command, from_ascii("\\lstlistoflistings"))) + command.erase(1, 3); + os << command; } diff --git a/src/insets/InsetInclude.cpp b/src/insets/InsetInclude.cpp index 06b5238113..3ae1b48965 100644 --- a/src/insets/InsetInclude.cpp +++ b/src/insets/InsetInclude.cpp @@ -962,8 +962,12 @@ void InsetInclude::validate(LaTeXFeatures & features) const 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"); + else + features.require("listings"); + } // Here we must do the fun stuff... // Load the file in the include if it needs diff --git a/src/insets/InsetListings.cpp b/src/insets/InsetListings.cpp index bec33b12cb..0693b5af84 100644 --- a/src/insets/InsetListings.cpp +++ b/src/insets/InsetListings.cpp @@ -55,6 +55,7 @@ namespace lyx { InsetListings::InsetListings(Buffer * buf, InsetListingsParams const & par) : InsetCaptionable(buf,"listing") { + params_.setMinted(buffer().params().use_minted); status_ = par.status(); } @@ -115,6 +116,32 @@ void InsetListings::latex(otexstream & os, OutputParams const & runparams) const // NOTE: I use {} to quote text, which is an experimental feature // of the listings package (see page 25 of the manual) bool const isInline = params().isInline(); + bool const use_minted = buffer().params().use_minted; + string minted_language; + string float_placement; + bool const isfloat = params().isFloat(); + if (use_minted && (isfloat || contains(param_string, "language="))) { + // Get float placement and/or language of the code, + // then remove the relative options. + vector opts = + getVectorFromString(param_string, ",", false); + for (int i = 0; i < opts.size(); ++i) { + if (prefixIs(opts[i], "float")) { + if (prefixIs(opts[i], "float=")) + float_placement = opts[i].substr(6); + opts.erase(opts.begin() + i--); + } + else if (prefixIs(opts[i], "language=")) { + minted_language = opts[i].substr(9); + opts.erase(opts.begin() + i--); + } + } + param_string = getStringFromVector(opts, ","); + } + // Minted needs a language specification + if (minted_language.empty()) + minted_language = "TeX"; + // get the paragraphs. We can not output them directly to given odocstream // because we can not yet determine the delimiter character of \lstinline docstring code; @@ -127,7 +154,7 @@ void InsetListings::latex(otexstream & os, OutputParams const & runparams) const // The listings package cannot deal with multi-byte-encoded // glyphs, except if full-unicode aware backends // such as XeTeX or LuaTeX are used, and with pLaTeX. - bool const multibyte_possible = runparams.isFullUnicode() + bool const multibyte_possible = use_minted || runparams.isFullUnicode() || (buffer().params().encoding().package() == Encoding::japanese && runparams.encoding->package() == Encoding::japanese); @@ -225,13 +252,40 @@ void InsetListings::latex(otexstream & os, OutputParams const & runparams) const } } docstring const delim(1, delimiters[pos]); - os << "\\lstinline"; - if (!param_string.empty()) - os << "[" << from_utf8(param_string) << "]"; - else if (pos >= delimiters.find('Q')) - // We need to terminate the command before the delimiter - os << " "; + if (use_minted) { + os << "\\mintinline"; + if (!param_string.empty()) + os << "[" << from_utf8(param_string) << "]"; + os << "{" << minted_language << "}"; + } else { + os << "\\lstinline"; + if (!param_string.empty()) + os << "[" << from_utf8(param_string) << "]"; + else if (pos >= delimiters.find('Q')) + // We need to terminate the command before + // the delimiter + os << " "; + } os << delim << code << delim; + } else if (use_minted) { + if (isfloat) { + os << breakln << "\\begin{listing}"; + if (!float_placement.empty()) + os << '[' << float_placement << "]"; + } + os << breakln << "\\begin{minted}"; + if (!param_string.empty()) + os << "[" << param_string << "]"; + os << "{" << minted_language << "}\n" + << code << breakln << "\\end{minted}\n"; + if (isfloat) { + OutputParams rp = runparams; + rp.moving_arg = true; + TexString caption = getCaption(rp); + if (!caption.str.empty()) + os << "\\caption{" << move(caption) << "}\n"; + os << "\\end{listing}\n"; + } } else { OutputParams rp = runparams; rp.moving_arg = true; @@ -387,7 +441,10 @@ docstring const InsetListings::buttonLabel(BufferView const & bv) const void InsetListings::validate(LaTeXFeatures & features) const { - features.require("listings"); + if (buffer().params().use_minted) + features.require("minted"); + else + features.require("listings"); features.useInsetLayout(getLayout()); string param_string = params().params(); if (param_string.find("\\color") != string::npos) @@ -420,7 +477,8 @@ TexString InsetListings::getCaption(OutputParams const & runparams) const // the caption may contain \label{} but the listings // package prefer caption={}, label={} TexString cap = os.release(); - if (!contains(cap.str, from_ascii("\\label{"))) + if (buffer().params().use_minted + || !contains(cap.str, from_ascii("\\label{"))) return cap; // convert from // blah1\label{blah2} blah3 diff --git a/src/insets/InsetListingsParams.cpp b/src/insets/InsetListingsParams.cpp index 4b90ce7e91..bab238ae1e 100644 --- a/src/insets/InsetListingsParams.cpp +++ b/src/insets/InsetListingsParams.cpp @@ -290,7 +290,7 @@ public: private: /// key is the name of the parameter typedef map ListingsParams; - ListingsParams all_params_; + ListingsParams all_params_[2]; }; @@ -299,349 +299,593 @@ ParValidator::ParValidator() docstring const empty_hint; docstring const style_hint = _("Use \\footnotesize, \\small, \\itshape, " "\\ttfamily or something like that"); - docstring const frame_hint = _("none, leftline, topline, bottomline, lines, " + docstring const frame_hint_mint = + _("none, leftline, topline, bottomline, lines, single"); + docstring const frame_hint_lst = + _("none, leftline, topline, bottomline, lines, " "single, shadowbox or subset of trblTRBL"); docstring const frameround_hint = _("Enter four letters (either t = round " "or f = square) for top right, bottom " "right, bottom left and top left corner."); - docstring const color_hint = _("Enter something like \\color{white}"); + docstring const color_hint_mint = + _("Previously defined color name as a string"); + docstring const color_hint_lst = + _("Enter something like \\color{white}"); + + // Listings package /// options copied from page 26 of listings manual // FIXME: add default parameters ... (which is not used now) - all_params_["float"] = + all_params_[0]["float"] = ListingsParam("false", true, SUBSETOF, "*tbph", empty_hint); - all_params_["floatplacement"] = + all_params_[0]["floatplacement"] = ListingsParam("tbp", false, SUBSETOF, "tbp", empty_hint); - all_params_["aboveskip"] = + all_params_[0]["aboveskip"] = ListingsParam("\\medskipamount", false, SKIP, "", empty_hint); - all_params_["belowskip"] = + all_params_[0]["belowskip"] = ListingsParam("\\medskipamount", false, SKIP, "", empty_hint); - all_params_["lineskip"] = + all_params_[0]["lineskip"] = ListingsParam("", false, SKIP, "", empty_hint); - all_params_["boxpos"] = + all_params_[0]["boxpos"] = ListingsParam("", false, SUBSETOF, "bct", empty_hint); - all_params_["print"] = + all_params_[0]["print"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["firstline"] = + all_params_[0]["firstline"] = ListingsParam("", false, INTEGER, "", empty_hint); - all_params_["lastline"] = + all_params_[0]["lastline"] = ListingsParam("", false, INTEGER, "", empty_hint); - all_params_["linerange"] = + all_params_[0]["linerange"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["showlines"] = + all_params_[0]["showlines"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["emptylines"] = + all_params_[0]["emptylines"] = ListingsParam("", false, ALL, "", _( "Expect a number with an optional * before it")); - all_params_["gobble"] = + all_params_[0]["gobble"] = ListingsParam("", false, INTEGER, "", empty_hint); - all_params_["style"] = + all_params_[0]["style"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["language"] = + all_params_[0]["language"] = ListingsParam("", false, ONEOF, allowed_languages, empty_hint); - all_params_["alsolanguage"] = + all_params_[0]["alsolanguage"] = ListingsParam("", false, ONEOF, allowed_languages, empty_hint); - all_params_["defaultdialect"] = + all_params_[0]["defaultdialect"] = ListingsParam("", false, ONEOF, allowed_languages, empty_hint); - all_params_["printpod"] = + all_params_[0]["printpod"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["usekeywordsintag"] = + all_params_[0]["usekeywordsintag"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["tagstyle"] = + all_params_[0]["tagstyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["markfirstintag"] = + all_params_[0]["markfirstintag"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["makemacrouse"] = + all_params_[0]["makemacrouse"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["basicstyle"] = + all_params_[0]["basicstyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["identifierstyle"] = + all_params_[0]["identifierstyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["commentstyle"] = + all_params_[0]["commentstyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["stringstyle"] = + all_params_[0]["stringstyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["keywordstyle"] = + all_params_[0]["keywordstyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["ndkeywordstyle"] = + all_params_[0]["ndkeywordstyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["classoffset"] = + all_params_[0]["classoffset"] = ListingsParam("", false, INTEGER, "", empty_hint); - all_params_["texcsstyle"] = + all_params_[0]["texcsstyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["directivestyle"] = + all_params_[0]["directivestyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["emph"] = + all_params_[0]["emph"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["moreemph"] = + all_params_[0]["moreemph"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deleteemph"] = + all_params_[0]["deleteemph"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["emphstyle"] = + all_params_[0]["emphstyle"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["delim"] = + all_params_[0]["delim"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["moredelim"] = + all_params_[0]["moredelim"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deletedelim"] = + all_params_[0]["deletedelim"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["extendedchars"] = + all_params_[0]["extendedchars"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["inputencoding"] = + all_params_[0]["inputencoding"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["upquote"] = + all_params_[0]["upquote"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["tabsize"] = + all_params_[0]["tabsize"] = ListingsParam("", false, INTEGER, "", empty_hint); - all_params_["showtabs"] = + all_params_[0]["showtabs"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["tab"] = + all_params_[0]["tab"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["showspaces"] = + all_params_[0]["showspaces"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["showstringspaces"] = + all_params_[0]["showstringspaces"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["formfeed"] = + all_params_[0]["formfeed"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["numbers"] = + all_params_[0]["numbers"] = ListingsParam("", false, ONEOF, "none\nleft\nright", empty_hint); - all_params_["stepnumber"] = + all_params_[0]["stepnumber"] = ListingsParam("", false, INTEGER, "", empty_hint); - all_params_["numberfirstline"] = + all_params_[0]["numberfirstline"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["numberstyle"] = + all_params_[0]["numberstyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["numbersep"] = + all_params_[0]["numbersep"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["numberblanklines"] = + all_params_[0]["numberblanklines"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["firstnumber"] = + all_params_[0]["firstnumber"] = ListingsParam("", false, ALL, "", _("auto, last or a number")); - all_params_["name"] = + all_params_[0]["name"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["thelstnumber"] = + all_params_[0]["thelstnumber"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["title"] = + all_params_[0]["title"] = ListingsParam("", false, ALL, "", empty_hint); // this option is not handled in the parameter box - all_params_["caption"] = + all_params_[0]["caption"] = ListingsParam("", false, ALL, "", _( "This parameter should not be entered here. Please use the caption " "edit box (when using the child document dialog) or " "menu Insert->Caption (when defining a listing inset)")); // this option is not handled in the parameter box - all_params_["label"] = + all_params_[0]["label"] = ListingsParam("", false, ALL, "",_( "This parameter should not be entered here. Please use the label " "edit box (when using the child document dialog) or " "menu Insert->Label (when defining a listing inset)")); - all_params_["nolol"] = + all_params_[0]["nolol"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["captionpos"] = + all_params_[0]["captionpos"] = ListingsParam("", false, SUBSETOF, "tb", empty_hint); - all_params_["abovecaptionskip"] = + all_params_[0]["abovecaptionskip"] = ListingsParam("", false, SKIP, "", empty_hint); - all_params_["belowcaptionskip"] = + all_params_[0]["belowcaptionskip"] = ListingsParam("", false, SKIP, "", empty_hint); - all_params_["linewidth"] = + all_params_[0]["linewidth"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["xleftmargin"] = + all_params_[0]["xleftmargin"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["xrightmargin"] = + all_params_[0]["xrightmargin"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["resetmargins"] = + all_params_[0]["resetmargins"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["breaklines"] = + all_params_[0]["breaklines"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["breakatwhitespace"] = + all_params_[0]["breakatwhitespace"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["prebreak"] = + all_params_[0]["prebreak"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["postbreak"] = + all_params_[0]["postbreak"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["breakindent"] = + all_params_[0]["breakindent"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["breakautoindent"] = + all_params_[0]["breakautoindent"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["frame"] = - ListingsParam("", false, ALL, "", frame_hint); - all_params_["frameround"] = + all_params_[0]["frame"] = + ListingsParam("", false, ALL, "", frame_hint_lst); + all_params_[0]["frameround"] = ListingsParam("", false, SUBSETOF, "tf", frameround_hint); - all_params_["framesep"] = + all_params_[0]["framesep"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["rulesep"] = + all_params_[0]["rulesep"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["framerule"] = + all_params_[0]["framerule"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["framexleftmargin"] = + all_params_[0]["framexleftmargin"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["framexrightmargin"] = + all_params_[0]["framexrightmargin"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["framextopmargin"] = + all_params_[0]["framextopmargin"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["framexbottommargin"] = + all_params_[0]["framexbottommargin"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["backgroundcolor"] = - ListingsParam("", false, ALL, "", color_hint ); - all_params_["rulecolor"] = - ListingsParam("", false, ALL, "", color_hint ); - all_params_["fillcolor"] = - ListingsParam("", false, ALL, "", color_hint ); - all_params_["rulesepcolor"] = - ListingsParam("", false, ALL, "", color_hint ); - all_params_["frameshape"] = + all_params_[0]["backgroundcolor"] = + ListingsParam("", false, ALL, "", color_hint_lst); + all_params_[0]["rulecolor"] = + ListingsParam("", false, ALL, "", color_hint_lst); + all_params_[0]["fillcolor"] = + ListingsParam("", false, ALL, "", color_hint_lst); + all_params_[0]["rulesepcolor"] = + ListingsParam("", false, ALL, "", color_hint_lst); + all_params_[0]["frameshape"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["index"] = + all_params_[0]["index"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["moreindex"] = + all_params_[0]["moreindex"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deleteindex"] = + all_params_[0]["deleteindex"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["indexstyle"] = + all_params_[0]["indexstyle"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["columns"] = + all_params_[0]["columns"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["flexiblecolumns"] = + all_params_[0]["flexiblecolumns"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["keepspaces"] = + all_params_[0]["keepspaces"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["basewidth"] = + all_params_[0]["basewidth"] = ListingsParam("", false, LENGTH, "", empty_hint); - all_params_["fontadjust"] = + all_params_[0]["fontadjust"] = ListingsParam("", true, TRUEFALSE, "", empty_hint); - all_params_["texcl"] = + all_params_[0]["texcl"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["mathescape"] = + all_params_[0]["mathescape"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["escapechar"] = + all_params_[0]["escapechar"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["escapeinside"] = + all_params_[0]["escapeinside"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["escapebegin"] = + all_params_[0]["escapebegin"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["escapeend"] = + all_params_[0]["escapeend"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["fancyvrb"] = + all_params_[0]["fancyvrb"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["fvcmdparams"] = + all_params_[0]["fvcmdparams"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["morefvcmdparams"] = + all_params_[0]["morefvcmdparams"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["keywordsprefix"] = + all_params_[0]["keywordsprefix"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["keywords"] = + all_params_[0]["keywords"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["morekeywords"] = + all_params_[0]["morekeywords"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deletekeywords"] = + all_params_[0]["deletekeywords"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["ndkeywords"] = + all_params_[0]["ndkeywords"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["morendkeywords"] = + all_params_[0]["morendkeywords"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deletendkeywords"] = + all_params_[0]["deletendkeywords"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["texcs"] = + all_params_[0]["texcs"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["moretexcs"] = + all_params_[0]["moretexcs"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deletetexcs"] = + all_params_[0]["deletetexcs"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["directives"] = + all_params_[0]["directives"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["moredirectives"] = + all_params_[0]["moredirectives"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deletedirectives"] = + all_params_[0]["deletedirectives"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["sensitive"] = + all_params_[0]["sensitive"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["alsoletter"] = + all_params_[0]["alsoletter"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["alsodigit"] = + all_params_[0]["alsodigit"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["alsoother"] = + all_params_[0]["alsoother"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["otherkeywords"] = + all_params_[0]["otherkeywords"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["tag"] = + all_params_[0]["tag"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["string"] = + all_params_[0]["string"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["morestring"] = + all_params_[0]["morestring"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deletestring"] = + all_params_[0]["deletestring"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["comment"] = + all_params_[0]["comment"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["morecomment"] = + all_params_[0]["morecomment"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deletecomment"] = + all_params_[0]["deletecomment"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["keywordcomment"] = + all_params_[0]["keywordcomment"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["morekeywordcomment"] = + all_params_[0]["morekeywordcomment"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deletekeywordcomment"] = + all_params_[0]["deletekeywordcomment"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["keywordcommentsemicolon"] = + all_params_[0]["keywordcommentsemicolon"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["podcomment"] = + all_params_[0]["podcomment"] = ListingsParam("", false, ALL, "", empty_hint); // the following are experimental listings features - all_params_["procnamekeys"] = + all_params_[0]["procnamekeys"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["moreprocnamekeys"] = + all_params_[0]["moreprocnamekeys"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deleteprocnamekeys"] = + all_params_[0]["deleteprocnamekeys"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["procnamestyle"] = + all_params_[0]["procnamestyle"] = ListingsParam("", false, ALL, "", style_hint); - all_params_["indexprocnames"] = + all_params_[0]["indexprocnames"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["hyperref"] = + all_params_[0]["hyperref"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["morehyperref"] = + all_params_[0]["morehyperref"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["deletehyperref"] = + all_params_[0]["deletehyperref"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["hyperanchor"] = + all_params_[0]["hyperanchor"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["hyperlink"] = + all_params_[0]["hyperlink"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["literate"] = + all_params_[0]["literate"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["lgrindef"] = + all_params_[0]["lgrindef"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["rangebeginprefix"] = + all_params_[0]["rangebeginprefix"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["rangebeginsuffix"] = + all_params_[0]["rangebeginsuffix"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["rangeendprefix"] = + all_params_[0]["rangeendprefix"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["rangeendsuffix"] = + all_params_[0]["rangeendsuffix"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["rangeprefix"] = + all_params_[0]["rangeprefix"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["rangesuffix"] = + all_params_[0]["rangesuffix"] = ListingsParam("", false, ALL, "", empty_hint); - all_params_["includerangemarker"] = + all_params_[0]["includerangemarker"] = ListingsParam("", false, TRUEFALSE, "", empty_hint); - all_params_["multicols"] = + all_params_[0]["multicols"] = ListingsParam("", false, INTEGER, "", empty_hint); + + // Minted package + + // This is not a real minted option and its only purpose + // is to get a caption for a floating listing. + all_params_[1]["caption"] = + ListingsParam("", false, ALL, "", _( + "This parameter should not be entered here. Please use the caption " + "edit box (when using the child document dialog) or " + "menu Insert->Caption (when defining a listing inset)")); + // The "label" minted option is being subverted here for the + // sake of getting a label for a floating listing. + all_params_[1]["label"] = + ListingsParam("", false, ALL, "",_( + "This parameter should not be entered here. Please use the label " + "edit box (when using the child document dialog) or " + "menu Insert->Label (when defining a listing inset)")); + // This is not a real minted option and its only purpose + // is to signal that this is a floating listing. + all_params_[1]["float"] = + ListingsParam("false", true, SUBSETOF, "*tbph", empty_hint); + all_params_[1]["chapter"] = + ListingsParam("", true, TRUEFALSE, "", _( + "Number floats by chapter")); + all_params_[1]["section"] = + ListingsParam("", true, TRUEFALSE, "", _( + "Number floats by section")); + all_params_[1]["cache"] = + ListingsParam("", false, TRUEFALSE, "", empty_hint); + all_params_[1]["cachedir"] = + ListingsParam("", false, ALL, "", _( + "default: _minted-")); + all_params_[1]["finalizecache"] = + ListingsParam("", false, TRUEFALSE, "", empty_hint); + all_params_[1]["frozencache"] = + ListingsParam("", false, TRUEFALSE, "", empty_hint); + all_params_[1]["draft"] = + ListingsParam("", false, TRUEFALSE, "", empty_hint); + all_params_[1]["final"] = + ListingsParam("", false, TRUEFALSE, "", empty_hint); + all_params_[1]["kpsewhich"] = + ListingsParam("", false, TRUEFALSE, "", empty_hint); + all_params_[1]["langlinenos"] = + ListingsParam("", false, TRUEFALSE, "", empty_hint); + all_params_[1]["newfloat"] = + ListingsParam("", false, TRUEFALSE, "", empty_hint); + all_params_[1]["outputdir"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["autogobble"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["baselinestretch"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["breakafter"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breakaftergroup"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["breakaftersymbolpre"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breakaftersymbolpost"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breakanywhere"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["breakanywheresymbolpre"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breakanywheresymbolpost"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breakautoindent"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["breakbefore"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breakbeforegroup"] = + ListingsParam("", true, ALL, "", empty_hint); + all_params_[1]["breakbeforesymbolpre"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breakbeforesymbolpost"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breakbytoken"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["breakbytokenanywhere"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["breakindent"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["breaklines"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["breaksymbol"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breaksymbolleft"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breaksymbolright"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["breaksymbolindent"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["breaksymbolindentleft"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["breaksymbolindentright"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["breaksymbolsep"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["breaksymbolsepleft"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["breaksymbolsepright"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["bgcolor"] = + ListingsParam("", false, ALL, "", color_hint_mint); + all_params_[1]["codetagify"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["curlyquotes"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["encoding"] = + ListingsParam("", false, ALL, "", _( + "Sets encoding expected by Pygments")); + all_params_[1]["escapeinside"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["firstline"] = + ListingsParam("", false, INTEGER, "", empty_hint); + all_params_[1]["firstnumber"] = + ListingsParam("", false, ALL, "", _( + "(auto | last | integer)")); + all_params_[1]["fontfamily"] = + ListingsParam("", false, ALL, "", _( + "A latex family such as tt, sf, rm")); + all_params_[1]["fontseries"] = + ListingsParam("", false, ALL, "", _( + "A latex series such as m, b, c, bx, sb")); + all_params_[1]["fontsize"] = + ListingsParam("", false, ALL, "", _( + "A latex name such as \\small")); + all_params_[1]["fontshape"] = + ListingsParam("", false, ALL, "", _( + "A latex shape such as n, it, sl, sc")); + all_params_[1]["formatcom"] = + ListingsParam("", false, ALL, "", empty_hint); + all_params_[1]["frame"] = + ListingsParam("", false, ONEOF, + "none\nleftline\ntopline\nbottomline\nlines\nsingle", + frame_hint_mint); + all_params_[1]["framerule"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["framesep"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["funcnamehighlighting"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["gobble"] = + ListingsParam("", false, INTEGER, "", empty_hint); + all_params_[1]["highlightcolor"] = + ListingsParam("", false, ALL, "", color_hint_mint); + all_params_[1]["highlightlines"] = + ListingsParam("", false, ALL, "", _( + "A range of lines such as {1,3-4}")); + all_params_[1]["keywordcase"] = + ListingsParam("", false, ONEOF, + "lower\nupper\ncapitalize", empty_hint); + 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.")); + all_params_[1]["lastline"] = + ListingsParam("", false, INTEGER, "", empty_hint); + all_params_[1]["linenos"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["numberfirstline"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["numbers"] = + ListingsParam("", false, ONEOF, + "left\nright\nboth\nnone", empty_hint); + all_params_[1]["mathescape"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["numberblanklines"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["numbersep"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["obeytabs"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["outencoding"] = + ListingsParam("", false, ALL, "", _( + "File encoding used by Pygments for highlighting")); + all_params_[1]["python3"] = + ListingsParam("", true, TRUEFALSE, "", _( + "Apply Python 3 highlighting")); + all_params_[1]["resetsmargins"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["rulecolor"] = + ListingsParam("", false, ALL, "", color_hint_mint); + all_params_[1]["samepage"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["showspaces"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["showtabs"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["space"] = + ListingsParam("", false, ALL, "", _( + "A macro. Default: \textvisiblespace")); + all_params_[1]["spacecolor"] = + ListingsParam("", false, ALL, "", color_hint_mint); + all_params_[1]["startinline"] = + ListingsParam("", true, TRUEFALSE, "", _("For PHP only")); + all_params_[1]["style"] = + ListingsParam("", false, ALL, "", _( + "The style used by Pygments")); + all_params_[1]["stepnumber"] = + ListingsParam("", false, INTEGER, "", empty_hint); + all_params_[1]["stepnumberfromfirst"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["stepnumberoffsetvalues"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["stripall"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["stripnl"] = + ListingsParam("", true, TRUEFALSE, "", empty_hint); + all_params_[1]["tab"] = + ListingsParam("", false, ALL, "", _( + "A macro to redefine visible tabs")); + all_params_[1]["tabcolor"] = + ListingsParam("", false, ALL, "", color_hint_mint); + all_params_[1]["tabsize"] = + ListingsParam("", false, INTEGER, "", empty_hint); + all_params_[1]["texcl"] = + ListingsParam("", true, TRUEFALSE, "", _( + "Enables latex code in comments")); + all_params_[1]["texcomments"] = + ListingsParam("", true, TRUEFALSE, "", _( + "Enables latex code in comments")); + all_params_[1]["xleftmargin"] = + ListingsParam("", false, LENGTH, "", empty_hint); + all_params_[1]["xrightmargin"] = + ListingsParam("", false, LENGTH, "", empty_hint); } docstring ParValidator::validate(string const & name, string const & par) const { + int p = InsetListingsParams::package(); + if (name.empty()) return _("Invalid (empty) listing parameter name."); if (name[0] == '?') { string suffix = trim(string(name, 1)); string param_names; - ListingsParams::const_iterator it = all_params_.begin(); - ListingsParams::const_iterator end = all_params_.end(); + ListingsParams::const_iterator it = all_params_[p].begin(); + ListingsParams::const_iterator end = all_params_[p].end(); for (; it != end; ++it) { if (suffix.empty() || contains(it->first, suffix)) { if (!param_names.empty()) @@ -659,8 +903,8 @@ docstring ParValidator::validate(string const & name, } // locate name in parameter table - ListingsParams::const_iterator it = all_params_.find(name); - if (it != all_params_.end()) { + ListingsParams::const_iterator it = all_params_[p].find(name); + if (it != all_params_[p].end()) { docstring msg = it->second.validate(par); if (msg.empty()) return msg; @@ -669,8 +913,8 @@ docstring ParValidator::validate(string const & name, } else { // otherwise, produce a meaningful error message. string matching_names; - ListingsParams::const_iterator end = all_params_.end(); - for (it = all_params_.begin(); it != end; ++it) { + ListingsParams::const_iterator end = all_params_[p].end(); + for (it = all_params_[p].begin(); it != end; ++it) { if (prefixIs(it->first, name)) { if (!matching_names.empty()) matching_names += ", "; @@ -689,9 +933,11 @@ docstring ParValidator::validate(string const & name, bool ParValidator::onoff(string const & name) const { + int p = InsetListingsParams::package(); + // locate name in parameter table - ListingsParams::const_iterator it = all_params_.find(name); - if (it != all_params_.end()) + ListingsParams::const_iterator it = all_params_[p].find(name); + if (it != all_params_[p].end()) return it->second.onoff_; else return false; @@ -702,6 +948,10 @@ bool ParValidator::onoff(string const & name) const // define a global ParValidator ParValidator * par_validator = 0; +// The package to be used by the global ParValidator +// (0 for listings, 1 for minted) +int InsetListingsParams::package_ = 0; + InsetListingsParams::InsetListingsParams() : inline_(false), params_(), status_(InsetCollapsable::Open) { diff --git a/src/insets/InsetListingsParams.h b/src/insets/InsetListingsParams.h index 7388acd3c4..e565e99dc8 100644 --- a/src/insets/InsetListingsParams.h +++ b/src/insets/InsetListingsParams.h @@ -70,6 +70,12 @@ public: /// void setInline(bool i) { inline_ = i; } + /// + void setMinted(bool use_minted) { package_ = use_minted ? 1 : 0; } + + /// + static int package() { return package_; } + /// get value of option \c param std::string getParamValue(std::string const & param) const; @@ -80,6 +86,9 @@ public: docstring validate() const; private: + /// listings or minted package (0 or 1, respectively) + static int package_; + /// inline or normal listings bool inline_; diff --git a/src/insets/InsetTOC.cpp b/src/insets/InsetTOC.cpp index 76a8dc9d1b..dabfd211c3 100644 --- a/src/insets/InsetTOC.cpp +++ b/src/insets/InsetTOC.cpp @@ -106,8 +106,12 @@ void InsetTOC::validate(LaTeXFeatures & features) const { InsetCommand::validate(features); features.useInsetLayout(getLayout()); - if (getCmdName() == "lstlistoflistings") - features.require("listings"); + if (getCmdName() == "lstlistoflistings") { + if (buffer().params().use_minted) + features.require("minted"); + else + features.require("listings"); + } } diff --git a/src/tex2lyx/TODO.txt b/src/tex2lyx/TODO.txt index 2c835dd64c..327420dbfd 100644 --- a/src/tex2lyx/TODO.txt +++ b/src/tex2lyx/TODO.txt @@ -151,6 +151,19 @@ Format LaTeX feature LyX feature btprint "bibbysection" 534 Chapterbib support \usepackage{chapterbib} \multibib child +544 Minted support + Non-floating: InsetListings + \begin{minted}[opts]{language} + ... + \end{minted} + Floating: + \begin{listing}[placement] + \begin{minted}[opts]{language} + ... + \end{minted} + \end{listing} + Inline (where '?' is any char): + \mintinline[opts]{language}?...? diff --git a/src/tex2lyx/test/CJK.lyx.lyx b/src/tex2lyx/test/CJK.lyx.lyx index 8206676c75..82bbba3171 100644 --- a/src/tex2lyx/test/CJK.lyx.lyx +++ b/src/tex2lyx/test/CJK.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/CJKutf8.lyx.lyx b/src/tex2lyx/test/CJKutf8.lyx.lyx index c1763bd7e9..7e3dbc883e 100644 --- a/src/tex2lyx/test/CJKutf8.lyx.lyx +++ b/src/tex2lyx/test/CJKutf8.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/DummyDocument.lyx.lyx b/src/tex2lyx/test/DummyDocument.lyx.lyx index 7c29fcbd7b..86e20d489b 100644 --- a/src/tex2lyx/test/DummyDocument.lyx.lyx +++ b/src/tex2lyx/test/DummyDocument.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/Dummy~Document.lyx.lyx b/src/tex2lyx/test/Dummy~Document.lyx.lyx index aef4283417..79bf881a68 100644 --- a/src/tex2lyx/test/Dummy~Document.lyx.lyx +++ b/src/tex2lyx/test/Dummy~Document.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/XeTeX-polyglossia.lyx.lyx b/src/tex2lyx/test/XeTeX-polyglossia.lyx.lyx index fc4eba169f..8162a985f9 100644 --- a/src/tex2lyx/test/XeTeX-polyglossia.lyx.lyx +++ b/src/tex2lyx/test/XeTeX-polyglossia.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/algo2e.lyx.lyx b/src/tex2lyx/test/algo2e.lyx.lyx index bc35d63921..39e9689787 100644 --- a/src/tex2lyx/test/algo2e.lyx.lyx +++ b/src/tex2lyx/test/algo2e.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/box-color-size-space-align.lyx.lyx b/src/tex2lyx/test/box-color-size-space-align.lyx.lyx index b29ce6501f..d399999a5d 100644 --- a/src/tex2lyx/test/box-color-size-space-align.lyx.lyx +++ b/src/tex2lyx/test/box-color-size-space-align.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/test-insets-basic.lyx.lyx b/src/tex2lyx/test/test-insets-basic.lyx.lyx index 9cc7935e52..0862f8a915 100644 --- a/src/tex2lyx/test/test-insets-basic.lyx.lyx +++ b/src/tex2lyx/test/test-insets-basic.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/test-insets.lyx.lyx b/src/tex2lyx/test/test-insets.lyx.lyx index af238c57c2..42fa3e628f 100644 --- a/src/tex2lyx/test/test-insets.lyx.lyx +++ b/src/tex2lyx/test/test-insets.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/test-memoir.lyx.lyx b/src/tex2lyx/test/test-memoir.lyx.lyx index 0a29c87d1a..e1dc00b824 100644 --- a/src/tex2lyx/test/test-memoir.lyx.lyx +++ b/src/tex2lyx/test/test-memoir.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/test-modules.lyx.lyx b/src/tex2lyx/test/test-modules.lyx.lyx index 9242388dc8..9f754c4661 100644 --- a/src/tex2lyx/test/test-modules.lyx.lyx +++ b/src/tex2lyx/test/test-modules.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/test-refstyle-theorems.lyx.lyx b/src/tex2lyx/test/test-refstyle-theorems.lyx.lyx index 43c605f223..fa573b6ff6 100644 --- a/src/tex2lyx/test/test-refstyle-theorems.lyx.lyx +++ b/src/tex2lyx/test/test-refstyle-theorems.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/test-scr.lyx.lyx b/src/tex2lyx/test/test-scr.lyx.lyx index fc5ba59767..35f494649e 100644 --- a/src/tex2lyx/test/test-scr.lyx.lyx +++ b/src/tex2lyx/test/test-scr.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/test-structure.lyx.lyx b/src/tex2lyx/test/test-structure.lyx.lyx index 7d22d6a8a6..1ec7c69c70 100644 --- a/src/tex2lyx/test/test-structure.lyx.lyx +++ b/src/tex2lyx/test/test-structure.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/test.lyx.lyx b/src/tex2lyx/test/test.lyx.lyx index 323239ee89..31e21063d3 100644 --- a/src/tex2lyx/test/test.lyx.lyx +++ b/src/tex2lyx/test/test.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/tex2lyx/test/verbatim.lyx.lyx b/src/tex2lyx/test/verbatim.lyx.lyx index 3d17c15ff0..ba3c82ec7a 100644 --- a/src/tex2lyx/test/verbatim.lyx.lyx +++ b/src/tex2lyx/test/verbatim.lyx.lyx @@ -1,5 +1,5 @@ #LyX file created by tex2lyx 2.3 -\lyxformat 543 +\lyxformat 544 \begin_document \begin_header \save_transient_properties true diff --git a/src/version.h b/src/version.h index dcbe74d4ba..1c42af3fb2 100644 --- a/src/version.h +++ b/src/version.h @@ -32,8 +32,8 @@ extern char const * const lyx_version_info; // Do not remove the comment below, so we get merge conflict in // independent branches. Instead add your own. -#define LYX_FORMAT_LYX 543 // uwestoehr: rename math_number_before entry to math_numbering_side -#define LYX_FORMAT_TEX2LYX 543 +#define LYX_FORMAT_LYX 544 // ef: minted support +#define LYX_FORMAT_TEX2LYX 544 #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX #ifndef _MSC_VER